From 32f58dfb11e699028c07c2180febc73197afa26f Mon Sep 17 00:00:00 2001 From: AloneLiberty <111039319+AloneLiberty@users.noreply.github.com> Date: Tue, 2 May 2023 00:37:39 +0300 Subject: [PATCH] 2.2.0 - Remove a lot of useless code from HardNestedSolver --- HardNestedSolver/cmdhfmfhard.c | 69 +- .../hardnested/hardnested_bruteforce.c | 39 +- .../hardnested/hardnested_tables.c | 614 ------- HardNestedSolver/pm3/ansi.h | 39 - HardNestedSolver/pm3/common.h | 64 - HardNestedSolver/pm3/commonutil.c | 227 +-- HardNestedSolver/pm3/commonutil.h | 38 - HardNestedSolver/pm3/comms.c | 909 ----------- HardNestedSolver/pm3/comms.h | 83 - HardNestedSolver/pm3/crc.c | 181 --- HardNestedSolver/pm3/crc.h | 93 -- HardNestedSolver/pm3/crc16.c | 352 ---- HardNestedSolver/pm3/crc16.h | 87 - HardNestedSolver/pm3/crc32.c | 50 - HardNestedSolver/pm3/crc32.h | 27 - HardNestedSolver/pm3/crc64.c | 96 -- HardNestedSolver/pm3/crc64.h | 26 - HardNestedSolver/pm3/fileutils.c | 1414 ----------------- HardNestedSolver/pm3/fileutils.h | 263 --- HardNestedSolver/pm3/pm3_cmd.h | 543 ------- HardNestedSolver/pm3/uart/README.md | 13 - HardNestedSolver/pm3/uart/uart.h | 81 - HardNestedSolver/pm3/uart/uart_posix.c | 630 -------- HardNestedSolver/pm3/uart/uart_win32.c | 411 ----- HardNestedSolver/pm3/ui.c | 376 +---- HardNestedSolver/pm3/ui.h | 11 - HardNestedSolver/pm3/util.c | 1238 +-------------- HardNestedSolver/pm3/util.h | 123 -- HardNestedSolver/pm3/util_darwin.h | 34 - HardNestedSolver/pm3/util_darwin.m | 103 -- setup.py | 106 +- 31 files changed, 63 insertions(+), 8277 deletions(-) delete mode 100755 HardNestedSolver/hardnested/hardnested_tables.c delete mode 100755 HardNestedSolver/pm3/comms.c delete mode 100755 HardNestedSolver/pm3/comms.h delete mode 100755 HardNestedSolver/pm3/crc.c delete mode 100755 HardNestedSolver/pm3/crc.h delete mode 100755 HardNestedSolver/pm3/crc16.c delete mode 100755 HardNestedSolver/pm3/crc16.h delete mode 100755 HardNestedSolver/pm3/crc32.c delete mode 100755 HardNestedSolver/pm3/crc32.h delete mode 100755 HardNestedSolver/pm3/crc64.c delete mode 100755 HardNestedSolver/pm3/crc64.h delete mode 100755 HardNestedSolver/pm3/fileutils.c delete mode 100755 HardNestedSolver/pm3/fileutils.h delete mode 100755 HardNestedSolver/pm3/pm3_cmd.h delete mode 100755 HardNestedSolver/pm3/uart/README.md delete mode 100755 HardNestedSolver/pm3/uart/uart.h delete mode 100755 HardNestedSolver/pm3/uart/uart_posix.c delete mode 100755 HardNestedSolver/pm3/uart/uart_win32.c delete mode 100755 HardNestedSolver/pm3/util_darwin.h delete mode 100755 HardNestedSolver/pm3/util_darwin.m diff --git a/HardNestedSolver/cmdhfmfhard.c b/HardNestedSolver/cmdhfmfhard.c index bb44b88..70c42ae 100755 --- a/HardNestedSolver/cmdhfmfhard.c +++ b/HardNestedSolver/cmdhfmfhard.c @@ -38,7 +38,6 @@ #include "hardnested/hardnested_bf_core.h" #include "hardnested/hardnested_bitarray_core.h" #include "pm3/ui.h" -#include "pm3/fileutils.h" #include "pm3/commonutil.h" #include "pm3/util_posix.h" #include "hardnested/tables.h" @@ -984,71 +983,6 @@ static void estimate_sum_a8(void) { } } -static int read_nonce_file(char *filename) { - - if (filename == NULL) { - PrintAndLogEx(WARNING, "Filename is NULL"); - return PM3_EINVARG; - } - FILE *fnonces = NULL; - char progress_text[80] = ""; - uint8_t read_buf[9]; - - num_acquired_nonces = 0; - if ((fnonces = fopen(filename, "rb")) == NULL) { - PrintAndLogEx(WARNING, "Could not open file " - _YELLOW_("%s"), filename); - return PM3_EFILE; - } - - snprintf(progress_text, 80, "Reading nonces from file " - _YELLOW_("%s"), filename); - hardnested_print_progress(0, progress_text, (float) (1LL << 47), 0); - size_t bytes_read = fread(read_buf, 1, 6, fnonces); - if (bytes_read != 6) { - PrintAndLogEx(ERR, "File reading error."); - fclose(fnonces); - return PM3_EFILE; - } - cuid = bytes_to_num(read_buf, 4); - uint8_t trgBlockNo = bytes_to_num(read_buf + 4, 1); - uint8_t trgKeyType = bytes_to_num(read_buf + 5, 1); - - bytes_read = fread(read_buf, 1, 9, fnonces); - while (bytes_read == 9) { - uint32_t nt_enc1 = bytes_to_num(read_buf, 4); - uint32_t nt_enc2 = bytes_to_num(read_buf + 4, 4); - uint8_t par_enc = bytes_to_num(read_buf + 8, 1); - add_nonce(nt_enc1, par_enc >> 4); - add_nonce(nt_enc2, par_enc & 0x0f); - num_acquired_nonces += 2; - bytes_read = fread(read_buf, 1, 9, fnonces); - } - fclose(fnonces); - - char progress_string[80]; - snprintf(progress_string, sizeof(progress_string), "Read %u nonces from file. cuid = %08x", num_acquired_nonces, - cuid); - hardnested_print_progress(num_acquired_nonces, progress_string, (float) (1LL << 47), 0); - snprintf(progress_string, sizeof(progress_string), "Target Block=%d, Keytype=%c", trgBlockNo, - trgKeyType == 0 ? 'A' : 'B'); - hardnested_print_progress(num_acquired_nonces, progress_string, (float) (1LL << 47), 0); - - bool got_match = false; - for (uint8_t i = 0; i < NUM_SUMS; i++) { - if (first_byte_Sum == sums[i]) { - first_byte_Sum = i; - got_match = true; - break; - } - } - if (got_match == false) { - PrintAndLogEx(FAILED, "No match for the First_Byte_Sum (%u), is the card a genuine MFC Ev1? ", first_byte_Sum); - return PM3_ESOFT; - } - return 0; -} - static noncelistentry_t *SearchFor2ndByte(uint8_t b1, uint8_t b2) { noncelistentry_t *p = nonces[b1].first; while (p != NULL) { @@ -1262,6 +1196,7 @@ static int simulate_acquire_nonces(uint32_t uid, char* path) { num_acquired_nonces += add_nonce(nt_enc, par_enc); total_num_nonces++; } + if (num_acquired_nonces % 256 == 0) { hardnested_print_progress(num_acquired_nonces, "Loading nonces from file", brute_force_depth, 0); } @@ -1283,7 +1218,7 @@ static int simulate_acquire_nonces(uint32_t uid, char* path) { if (got_match == false) { PrintAndLogEx(FAILED, "No match for the First_Byte_Sum (%u), is the card a genuine MFC Ev1? ", first_byte_Sum); - return PM3_ESOFT; + return -1; } hardnested_stage |= CHECK_2ND_BYTES; diff --git a/HardNestedSolver/hardnested/hardnested_bruteforce.c b/HardNestedSolver/hardnested/hardnested_bruteforce.c index 064c06a..6c35a7a 100755 --- a/HardNestedSolver/hardnested/hardnested_bruteforce.c +++ b/HardNestedSolver/hardnested/hardnested_bruteforce.c @@ -56,17 +56,12 @@ THE SOFTWARE. #include #include -//#include "../pm3/common.h" -//#include "../cmdhfmfhard.h" #include "hardnested_bf_core.h" #include "../pm3/ui.h" -//#include "../pm3/util.h" #include "../pm3/util_posix.h" #include "../crapto1.h" #include "../parity.h" #include "../cmdhfmfhard.h" -//#include "../pm3/fileutils.h" -//#include "../pm3/pm3_cmd.h" #include "hardnested_benchmark_data.h" #define NUM_BRUTE_FORCE_THREADS (num_CPUs()) @@ -77,8 +72,7 @@ THE SOFTWARE. #endif #define DEFAULT_BRUTE_FORCE_RATE (120000000.0) // if benchmark doesn't succeed #define TEST_BENCH_SIZE (6000) // number of odd and even states for brute force benchmark -#define TEST_BENCH_FILENAME "hardnested_bf_bench_data.bin" -//#define WRITE_BENCH_FILE + #ifdef _MSC_VER #include #include @@ -309,37 +303,6 @@ void prepare_bf_test_nonces(noncelist_t *nonces, uint8_t best_first_byte) { } } - -#if defined (WRITE_BENCH_FILE) -static void write_benchfile(statelist_t *candidates) { - - PrintAndLogEx(NORMAL, "Writing brute force benchmark data in " RESOURCES_SUBDIR " subdirectory..."); - FILE *benchfile = fopen(RESOURCES_SUBDIR TEST_BENCH_FILENAME, "wb"); - if (benchfile == NULL) { - PrintAndLogEx(ERR, "Can't write " RESOURCES_SUBDIR TEST_BENCH_FILENAME", abort!"); - return; - } - fwrite(&nonces_to_bruteforce, 1, sizeof(nonces_to_bruteforce), benchfile); - for (uint32_t i = 0; i < nonces_to_bruteforce; i++) { - fwrite(&(bf_test_nonce[i]), 1, sizeof(bf_test_nonce[i]), benchfile); - fwrite(&(bf_test_nonce_par[i]), 1, sizeof(bf_test_nonce_par[i]), benchfile); - } - uint32_t num_states = MIN(candidates->len[EVEN_STATE], TEST_BENCH_SIZE); - fwrite(&num_states, 1, sizeof(num_states), benchfile); - for (uint32_t i = 0; i < num_states; i++) { - fwrite(&(candidates->states[EVEN_STATE][i]), 1, sizeof(uint32_t), benchfile); - } - num_states = MIN(candidates->len[ODD_STATE], TEST_BENCH_SIZE); - fwrite(&num_states, 1, sizeof(num_states), benchfile); - for (uint32_t i = 0; i < num_states; i++) { - fwrite(&(candidates->states[ODD_STATE][i]), 1, sizeof(uint32_t), benchfile); - } - fclose(benchfile); - PrintAndLogEx(NORMAL, "Done"); -} -#endif - - bool brute_force_bs(float *bf_rate, statelist_t *candidates, uint32_t cuid, uint32_t num_acquired_nonces, uint64_t maximum_states, noncelist_t *nonces, uint8_t *best_first_bytes, uint64_t *found_key) { #if defined (WRITE_BENCH_FILE) write_benchfile(candidates); diff --git a/HardNestedSolver/hardnested/hardnested_tables.c b/HardNestedSolver/hardnested/hardnested_tables.c deleted file mode 100755 index 837088a..0000000 --- a/HardNestedSolver/hardnested/hardnested_tables.c +++ /dev/null @@ -1,614 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (C) 2015, 2016 by piwi -// -// This code is licensed to you under the terms of the GNU GPL, version 2 or, -// at your option, any later version. See the LICENSE.txt file for the text of -// the license. -//----------------------------------------------------------------------------- -// Implements a card only attack based on crypto text (encrypted nonces -// received during a nested authentication) only. Unlike other card only -// attacks this doesn't rely on implementation errors but only on the -// inherent weaknesses of the crypto1 cypher. Described in -// Carlo Meijer, Roel Verdult, "Ciphertext-only Cryptanalysis on Hardened -// Mifare Classic Cards" in Proceedings of the 22nd ACM SIGSAC Conference on -// Computer and Communications Security, 2015 -//----------------------------------------------------------------------------- -// -// This program calculates tables with possible states for a given -// bitflip property. -// -//----------------------------------------------------------------------------- - -// To compile it: -// gcc -I../../../common -I../../../include -o hardnested_tables hardnested_tables.c - -#include -#include -#include -#ifndef __APPLE__ -#include -#endif -#include -#include -#include -#include "../crapto1.h" -#include "../parity.h" - - -#define NUM_PART_SUMS 9 -#define BITFLIP_2ND_BYTE 0x0200 - -typedef enum { - EVEN_STATE = 0, - ODD_STATE = 1 -} odd_even_t; - - -static uint16_t PartialSumProperty(uint32_t state, odd_even_t odd_even) { - uint16_t sum = 0; - for (uint16_t j = 0; j < 16; j++) { - uint32_t st = state; - uint16_t part_sum = 0; - if (odd_even == ODD_STATE) { - part_sum ^= filter(st); - for (uint16_t i = 0; i < 4; i++) { - st = (st << 1) | ((j >> (3 - i)) & 0x01) ; - part_sum ^= filter(st); - } - part_sum ^= 1; // XOR 1 cancelled out for the other 8 bits - } else { - for (uint16_t i = 0; i < 4; i++) { - st = (st << 1) | ((j >> (3 - i)) & 0x01) ; - part_sum ^= filter(st); - } - } - sum += part_sum; - } - return sum; -} - - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// bitarray functions - -#if defined (_WIN32) -#define malloc_bitarray(x) __builtin_assume_aligned(_aligned_malloc((x), __BIGGEST_ALIGNMENT__), __BIGGEST_ALIGNMENT__) -#define free_bitarray(x) _aligned_free(x) -#elif defined (__APPLE__) -static void *malloc_bitarray(size_t x) { - char *allocated_memory; - if (posix_memalign((void **)&allocated_memory, __BIGGEST_ALIGNMENT__, x)) { - return NULL; - } else { - return __builtin_assume_aligned(allocated_memory, __BIGGEST_ALIGNMENT__); - } -} -#define free_bitarray(x) free(x) -#else -//#define malloc_bitarray(x) memalign(__BIGGEST_ALIGNMENT__, (x)) -#define malloc_bitarray(x) __builtin_assume_aligned(memalign(__BIGGEST_ALIGNMENT__, (x)), __BIGGEST_ALIGNMENT__); -#define free_bitarray(x) free(x) -#endif - -static inline void clear_bitarray24(uint32_t *bitarray) { - memset(bitarray, 0x00, sizeof(uint32_t) * (1 << 19)); -} - -static inline uint32_t test_bit24(const uint32_t *bitarray, uint32_t index) { - return bitarray[index >> 5] & (0x80000000 >> (index & 0x0000001f)); -} - -static inline void set_bit24(uint32_t *bitarray, uint32_t index) { - bitarray[index >> 5] |= 0x80000000 >> (index & 0x0000001f); -} - -static inline uint32_t next_state(const uint32_t *bitset, uint32_t state) { - if (++state == 1 << 24) { - return 1 << 24; - } - - uint32_t index = state >> 5; - uint_fast8_t bit = state & 0x1f; - uint32_t line = bitset[index] << bit; - while (bit <= 0x1f) { - if (line & 0x80000000) { - return state; - } - state++; - bit++; - line <<= 1; - } - - index++; - while (bitset[index] == 0x00000000 && state < 1 << 24) { - index++; - state += 0x20; - } - - if (state >= 1 << 24) { - return 1 << 24; - } -#if defined __GNUC__ - return state + __builtin_clz(bitset[index]); -#else - bit = 0x00; - line = bitset[index]; - while (bit <= 0x1f) { - if (line & 0x80000000) { - return state; - } - state++; - bit++; - line <<= 1; - } - return 1 << 24; -#endif -} - - -static inline uint32_t next_not_state(const uint32_t *bitset, uint32_t state) { - if (++state == 1 << 24) return 1 << 24; - uint32_t index = state >> 5; - uint_fast8_t bit = state & 0x1f; - uint32_t line = bitset[index] << bit; - while (bit <= 0x1f) { - if ((line & 0x80000000) == 0) return state; - state++; - bit++; - line <<= 1; - } - index++; - while (bitset[index] == 0xffffffff && state < 1 << 24) { - index++; - state += 0x20; - } - if (state >= 1 << 24) return 1 << 24; -#if defined __GNUC__ - return state + __builtin_clz(~bitset[index]); -#else - bit = 0x00; - line = bitset[index]; - while (bit <= 0x1f) { - if ((line & 0x80000000) == 0) return state; - state++; - bit++; - line <<= 1; - } - return 1 << 24; -#endif -} - - -static inline uint32_t bitcount(uint32_t a) { -#if defined __GNUC__ - return __builtin_popcountl(a); -#else - a = a - ((a >> 1) & 0x55555555); - a = (a & 0x33333333) + ((a >> 2) & 0x33333333); - return (((a + (a >> 4)) & 0x0f0f0f0f) * 0x01010101) >> 24; -#endif -} - - -static inline uint32_t count_states(uint32_t *bitset) { - uint32_t count = 0; - for (uint32_t i = 0; i < (1 << 19); i++) { - count += bitcount(bitset[i]); - } - return count; -} - - -static void write_bitflips_file(odd_even_t odd_even, uint16_t bitflip, int sum_a0, uint32_t *bitset, uint32_t count) { - char filename[80]; - snprintf(filename, sizeof(filename), "bitflip_%d_%03" PRIx16 "_sum%d_states.bin", odd_even, bitflip, sum_a0); - FILE *outfile = fopen(filename, "wb"); - fwrite(&count, 1, sizeof(count), outfile); - fwrite(bitset, 1, sizeof(uint32_t) * (1 << 19), outfile); - fclose(outfile); -} - - -uint32_t *restrict part_sum_a0_bitarrays[2][NUM_PART_SUMS]; - -static void init_part_sum_bitarrays(void) { - printf("init_part_sum_bitarrays()..."); - for (odd_even_t odd_even = EVEN_STATE; odd_even <= ODD_STATE; odd_even++) { - for (uint16_t part_sum_a0 = 0; part_sum_a0 < NUM_PART_SUMS; part_sum_a0++) { - part_sum_a0_bitarrays[odd_even][part_sum_a0] = (uint32_t *)malloc_bitarray(sizeof(uint32_t) * (1 << 19)); - if (part_sum_a0_bitarrays[odd_even][part_sum_a0] == NULL) { - printf("Out of memory error in init_part_suma0_statelists(). Aborting...\n"); - exit(4); - } - clear_bitarray24(part_sum_a0_bitarrays[odd_even][part_sum_a0]); - } - } - for (odd_even_t odd_even = EVEN_STATE; odd_even <= ODD_STATE; odd_even++) { - //printf("(%d, %" PRIu16 ")...", odd_even, part_sum_a0); - for (uint32_t state = 0; state < (1 << 20); state++) { - uint16_t part_sum_a0 = PartialSumProperty(state, odd_even) / 2; - for (uint16_t low_bits = 0; low_bits < 1 << 4; low_bits++) { - set_bit24(part_sum_a0_bitarrays[odd_even][part_sum_a0], state << 4 | low_bits); - } - } - } - printf("done.\n"); -} - - -static void free_part_sum_bitarrays(void) { - printf("free_part_sum_bitarrays()..."); - for (int16_t part_sum_a0 = (NUM_PART_SUMS - 1); part_sum_a0 >= 0; part_sum_a0--) { - free_bitarray(part_sum_a0_bitarrays[ODD_STATE][part_sum_a0]); - } - for (int16_t part_sum_a0 = (NUM_PART_SUMS - 1); part_sum_a0 >= 0; part_sum_a0--) { - free_bitarray(part_sum_a0_bitarrays[EVEN_STATE][part_sum_a0]); - } - printf("done.\n"); -} - -uint32_t *restrict sum_a0_bitarray[2]; - -void init_sum_bitarray(uint16_t sum_a0) { - printf("init_sum_bitarray()...\n"); - for (odd_even_t odd_even = EVEN_STATE; odd_even <= ODD_STATE; odd_even++) { - sum_a0_bitarray[odd_even] = (uint32_t *)malloc_bitarray(sizeof(uint32_t) * (1 << 19)); - if (sum_a0_bitarray[odd_even] == NULL) { - printf("Out of memory error in init_sum_bitarrays(). Aborting...\n"); - exit(4); - } - clear_bitarray24(sum_a0_bitarray[odd_even]); - } - for (uint8_t p = 0; p < NUM_PART_SUMS; p++) { - for (uint8_t q = 0; q < NUM_PART_SUMS; q++) { - if (sum_a0 == 2 * p * (16 - 2 * q) + (16 - 2 * p) * 2 * q) { - for (uint32_t i = 0; i < (1 << 19); i++) { - sum_a0_bitarray[EVEN_STATE][i] |= part_sum_a0_bitarrays[EVEN_STATE][q][i]; - sum_a0_bitarray[ODD_STATE][i] |= part_sum_a0_bitarrays[ODD_STATE][p][i]; - } - } - } - } - for (odd_even_t odd_even = EVEN_STATE; odd_even <= ODD_STATE; odd_even++) { - uint32_t count = count_states(sum_a0_bitarray[odd_even]); - printf("sum_a0_bitarray[%s] has %u states (%5.2f%%)\n", odd_even == EVEN_STATE ? "even" : "odd ", count, (float)count / (1 << 24) * 100.0); - } - printf("done.\n"); -} - - -static void free_sum_bitarray(void) { - printf("free_sum_bitarray()..."); - free_bitarray(sum_a0_bitarray[ODD_STATE]); - free_bitarray(sum_a0_bitarray[EVEN_STATE]); - printf("done.\n"); -} - - -static void precalculate_bit0_bitflip_bitarrays(uint8_t const bitflip, uint16_t const sum_a0) { - // #define TEST_RUN -#ifdef TEST_RUN -#define NUM_TEST_STATES (1<<10) -#else -#define NUM_TEST_STATES (1<<23) -#endif - - time_t start_time = time(NULL); - time_t last_check_time = start_time; - - uint32_t *restrict test_bitarray[2]; - uint32_t *restrict test_not_bitarray[2]; - - test_bitarray[EVEN_STATE] = malloc_bitarray(sizeof(uint32_t) * (1 << 19)); - clear_bitarray24(test_bitarray[EVEN_STATE]); - test_bitarray[ODD_STATE] = malloc_bitarray(sizeof(uint32_t) * (1 << 19)); - clear_bitarray24(test_bitarray[ODD_STATE]); - - test_not_bitarray[EVEN_STATE] = malloc_bitarray(sizeof(uint32_t) * (1 << 19)); - clear_bitarray24(test_not_bitarray[EVEN_STATE]); - test_not_bitarray[ODD_STATE] = malloc_bitarray(sizeof(uint32_t) * (1 << 19)); - clear_bitarray24(test_not_bitarray[ODD_STATE]); - - uint32_t count[2]; - bool all_odd_states_are_possible_for_notbitflip = false; - - printf("\n\nStarting search for crypto1 states resulting in bitflip property 0x%03x...\n", bitflip); - for (uint32_t even_state = next_state(sum_a0_bitarray[EVEN_STATE], -1); even_state < NUM_TEST_STATES; even_state = next_state(sum_a0_bitarray[EVEN_STATE], even_state)) { - bool even_state_is_possible = false; - time_t time_now = time(NULL); - if (difftime(time_now, last_check_time) > 5 * 60) { // print status every 5 minutes - float runtime = difftime(time_now, start_time); - float remaining_time = runtime * ((1 << 23) - even_state) / even_state; - printf("\n%1.1f hours elapsed, expected completion in %1.1f hours (%1.1f days)", runtime / 3600, remaining_time / 3600, remaining_time / 3600 / 24); - last_check_time = time_now; - } - for (uint32_t odd_state = next_state(sum_a0_bitarray[ODD_STATE], -1); odd_state < (1 << 24); odd_state = next_state(test_bitarray[ODD_STATE], odd_state)) { - if (even_state_is_possible && test_bit24(test_bitarray[ODD_STATE], odd_state)) continue; - // load crypto1 state - struct Crypto1State cs; - cs.odd = odd_state >> 4; - cs.even = even_state >> 4; - - // track flipping bits in state - struct Crypto1DeltaState { - uint_fast8_t odd; - uint_fast8_t even; - } cs_delta; - cs_delta.odd = 0; - cs_delta.even = 0; - - uint_fast16_t keystream = 0; - - // decrypt 9 bits - for (int i = 0; i < 9; i++) { - uint_fast8_t keystream_bit = filter(cs.odd & 0x000fffff) ^ filter((cs.odd & 0x000fffff) ^ cs_delta.odd); - keystream = keystream << 1 | keystream_bit; - uint_fast8_t nt_bit = BIT(bitflip, i) ^ keystream_bit; - uint_fast8_t LSFR_feedback = BIT(cs_delta.odd, 2) ^ BIT(cs_delta.even, 2) ^ BIT(cs_delta.odd, 3); - - cs_delta.even = cs_delta.even << 1 | (LSFR_feedback ^ nt_bit); - uint_fast8_t tmp = cs_delta.odd; - cs_delta.odd = cs_delta.even; - cs_delta.even = tmp; - - cs.even = cs.odd; - if (i & 1) { - cs.odd = odd_state >> (7 - i) / 2; - } else { - cs.odd = even_state >> (7 - i) / 2; - } - } - - if (evenparity32(keystream) == evenparity32(bitflip)) { - // found valid bitflip state - even_state_is_possible = true; - set_bit24(test_bitarray[EVEN_STATE], even_state); - set_bit24(test_bitarray[EVEN_STATE], 1 << 23 | even_state); - set_bit24(test_bitarray[ODD_STATE], odd_state); - } else { - // found valid !bitflip state - set_bit24(test_not_bitarray[EVEN_STATE], even_state); - set_bit24(test_not_bitarray[EVEN_STATE], 1 << 23 | even_state); - set_bit24(test_not_bitarray[ODD_STATE], odd_state); - } - } - if (!even_state_is_possible) { - all_odd_states_are_possible_for_notbitflip = true; - } - } - - printf("\nAnalysis completed. Checking for effective bitflip properties...\n"); - for (odd_even_t odd_even = EVEN_STATE; odd_even <= ODD_STATE; odd_even++) { - count[odd_even] = count_states(test_bitarray[odd_even]); - if (count[odd_even] != 1 << 24) { - printf("Writing %u possible %s states for bitflip property %03x (%u (%1.2f%%) states eliminated)\n", - count[odd_even], - odd_even == EVEN_STATE ? "even" : "odd", - bitflip, - (1 << 24) - count[odd_even], - (float)((1 << 24) - count[odd_even]) / (1 << 24) * 100.0); -#ifndef TEST_RUN - write_bitflips_file(odd_even, bitflip, sum_a0, test_bitarray[odd_even], count[odd_even]); -#endif - } else { - printf("All %s states for bitflip property %03x are possible. No file written.\n", odd_even == EVEN_STATE ? "even" : "odd", bitflip); - } - } - uint32_t *restrict test_bitarray_2nd = malloc_bitarray(sizeof(uint32_t) * (1 << 19)); - clear_bitarray24(test_bitarray_2nd); - for (odd_even_t odd_even = EVEN_STATE; odd_even <= ODD_STATE; odd_even++) { - if (count[odd_even] != 1 << 24) { - for (uint32_t state = 0; state < (1 << 24); state += 1 << 4) { - uint32_t line = test_bitarray[odd_even][state >> 5]; - uint16_t half_line = (state & 0x000000010) ? line & 0x0000ffff : line >> 16; - if (half_line != 0) { - for (uint32_t low_bits = 0; low_bits < (1 << 4); low_bits++) { - set_bit24(test_bitarray_2nd, low_bits << 20 | state >> 4); - } - } - } - count[odd_even] = count_states(test_bitarray_2nd); - if (count[odd_even] != 1 << 24) { - printf("Writing %u possible %s states for bitflip property %03x (%u (%1.2f%%) states eliminated)\n", - count[odd_even], - odd_even == EVEN_STATE ? "even" : "odd", - bitflip | BITFLIP_2ND_BYTE, - (1 << 24) - count[odd_even], - (float)((1 << 24) - count[odd_even]) / (1 << 24) * 100.0); -#ifndef TEST_RUN - write_bitflips_file(odd_even, bitflip | BITFLIP_2ND_BYTE, sum_a0, test_bitarray_2nd, count[odd_even]); -#endif - } else { - printf("All %s states for bitflip property %03x are possible. No file written.\n", odd_even == EVEN_STATE ? "even" : "odd", bitflip | BITFLIP_2ND_BYTE); - } - } else { - printf("All %s states for bitflip property %03x are possible. No file written.\n", odd_even == EVEN_STATE ? "even" : "odd", bitflip | BITFLIP_2ND_BYTE); - } - } - - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // second run for the remaining "not bitflip" states - printf("\n\nStarting search for crypto1 states resulting in bitflip property 0x%03x...", bitflip | 0x100); - start_time = time(NULL); - last_check_time = start_time; - for (uint32_t even_state = next_state(sum_a0_bitarray[EVEN_STATE], -1); even_state < NUM_TEST_STATES; even_state = next_state(sum_a0_bitarray[EVEN_STATE], even_state)) { - bool even_state_is_possible = test_bit24(test_not_bitarray[EVEN_STATE], even_state); - time_t time_now = time(NULL); - if (difftime(time_now, last_check_time) > 5 * 60) { // print status every 5 minutes - float runtime = difftime(time_now, start_time); - float remaining_time = runtime * ((1 << 23) - even_state) / even_state; - printf("\n%1.1f hours elapsed, expected completion in %1.1f hours (%1.1f days)", runtime / 3600, remaining_time / 3600, remaining_time / 3600 / 24); - last_check_time = time_now; - } - for (uint32_t odd_state = next_state(sum_a0_bitarray[ODD_STATE], -1); odd_state < (1 << 24); odd_state = next_state(sum_a0_bitarray[ODD_STATE], odd_state)) { - if (even_state_is_possible) { - if (all_odd_states_are_possible_for_notbitflip) break; - if (test_bit24(test_not_bitarray[ODD_STATE], odd_state)) continue; - } - // load crypto1 state - struct Crypto1State cs; - cs.odd = odd_state >> 4; - cs.even = even_state >> 4; - - // track flipping bits in state - struct Crypto1DeltaState { - uint_fast8_t odd; - uint_fast8_t even; - } cs_delta; - cs_delta.odd = 0; - cs_delta.even = 0; - - uint_fast16_t keystream = 0; - // uint_fast16_t nt = 0; - - // decrypt 9 bits - for (int i = 0; i < 9; i++) { - uint_fast8_t keystream_bit = filter(cs.odd & 0x000fffff) ^ filter((cs.odd & 0x000fffff) ^ cs_delta.odd); - keystream = keystream << 1 | keystream_bit; - uint_fast8_t nt_bit = BIT(bitflip | 0x100, i) ^ keystream_bit; - uint_fast8_t LSFR_feedback = BIT(cs_delta.odd, 2) ^ BIT(cs_delta.even, 2) ^ BIT(cs_delta.odd, 3); - - cs_delta.even = cs_delta.even << 1 | (LSFR_feedback ^ nt_bit); - uint_fast8_t tmp = cs_delta.odd; - cs_delta.odd = cs_delta.even; - cs_delta.even = tmp; - - cs.even = cs.odd; - if (i & 1) { - cs.odd = odd_state >> (7 - i) / 2; - } else { - cs.odd = even_state >> (7 - i) / 2; - } - } - - if (evenparity32(keystream) != evenparity32(bitflip)) { - // found valid !bitflip state - even_state_is_possible = true; - set_bit24(test_not_bitarray[EVEN_STATE], even_state); - set_bit24(test_not_bitarray[EVEN_STATE], 1 << 23 | even_state); - set_bit24(test_not_bitarray[ODD_STATE], odd_state); - } - } - } - - printf("\nAnalysis completed. Checking for effective !bitflip properties...\n"); - for (odd_even_t odd_even = EVEN_STATE; odd_even <= ODD_STATE; odd_even++) { - count[odd_even] = count_states(test_not_bitarray[odd_even]); - if (count[odd_even] != 1 << 24) { - printf("Writing %u possible %s states for bitflip property %03x (%u (%1.2f%%) states eliminated)\n", - count[odd_even], - odd_even == EVEN_STATE ? "even" : "odd", - bitflip | 0x100, - (1 << 24) - count[odd_even], - (float)((1 << 24) - count[odd_even]) / (1 << 24) * 100.0); -#ifndef TEST_RUN - write_bitflips_file(odd_even, bitflip | 0x100, sum_a0, test_not_bitarray[odd_even], count[odd_even]); -#endif - } else { - printf("All %s states for bitflip property %03x are possible. No file written.\n", odd_even == EVEN_STATE ? "even" : "odd", bitflip | 0x100); - } - } - - clear_bitarray24(test_bitarray_2nd); - for (odd_even_t odd_even = EVEN_STATE; odd_even <= ODD_STATE; odd_even++) { - if (count[odd_even] != 1 << 24) { - for (uint32_t state = 0; state < (1 << 24); state += 1 << 4) { - uint32_t line = test_not_bitarray[odd_even][state >> 5]; - uint16_t half_line = (state & 0x000000010) ? line & 0x0000ffff : line >> 16; - if (half_line != 0) { - for (uint32_t low_bits = 0; low_bits < (1 << 4); low_bits++) { - set_bit24(test_bitarray_2nd, low_bits << 20 | state >> 4); - } - } - } - count[odd_even] = count_states(test_bitarray_2nd); - if (count[odd_even] != 1 << 24) { - printf("Writing %u possible %s states for bitflip property %03x (%u (%1.2f%%) states eliminated)\n", - count[odd_even], - odd_even == EVEN_STATE ? "even" : "odd", - bitflip | 0x100 | BITFLIP_2ND_BYTE, - (1 << 24) - count[odd_even], - (float)((1 << 24) - count[odd_even]) / (1 << 24) * 100.0); -#ifndef TEST_RUN - write_bitflips_file(odd_even, bitflip | 0x100 | BITFLIP_2ND_BYTE, sum_a0, test_bitarray_2nd, count[odd_even]); -#endif - } else { - 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); - } - } else { - 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); - } - } - - free_bitarray(test_bitarray_2nd); - free_bitarray(test_not_bitarray[ODD_STATE]); - free_bitarray(test_not_bitarray[EVEN_STATE]); - free_bitarray(test_bitarray[ODD_STATE]); - free_bitarray(test_bitarray[EVEN_STATE]); - exit(0); -} - - -//int main(int argc, char *argv[]) { -// -// unsigned int bitflip_in; -// int sum_a0 = 0; -// -// printf("Create tables required by hardnested attack.\n"); -// printf("Expect a runtime in the range of days or weeks.\n"); -// printf("Single thread only. If you want to use several threads, start it multiple times :-)\n\n"); -// -// if (argc != 2 && argc != 3) { -// printf(" syntax: %s []\n\n", argv[0]); -// printf(" example: %s 1f\n", argv[0]); -// return 1; -// } -// -// sscanf(argv[1], "%x", &bitflip_in); -// -// if (bitflip_in > 255) { -// printf("Bitflip property must be less than or equal to 0xff\n\n"); -// return 1; -// } -// -// if (argc == 3) { -// sscanf(argv[2], "%d", &sum_a0); -// } -// -// switch (sum_a0) { -// case 0: -// case 32: -// case 56: -// case 64: -// case 80: -// case 96: -// case 104: -// case 112: -// case 120: -// case 128: -// case 136: -// case 144: -// case 152: -// case 160: -// case 176: -// case 192: -// case 200: -// case 224: -// case 256: -// break; -// default: -// sum_a0 = -1; -// } -// -// printf("Calculating for bitflip = %02x, sum_a0 = %d\n", bitflip_in, sum_a0); -// -// init_part_sum_bitarrays(); -// init_sum_bitarray(sum_a0); -// -// precalculate_bit0_bitflip_bitarrays(bitflip_in, sum_a0); -// -// free_sum_bitarray(); -// free_part_sum_bitarrays(); -// -// return 0; -//} diff --git a/HardNestedSolver/pm3/ansi.h b/HardNestedSolver/pm3/ansi.h index 20815bc..71705ab 100755 --- a/HardNestedSolver/pm3/ansi.h +++ b/HardNestedSolver/pm3/ansi.h @@ -21,45 +21,11 @@ #define AEND "\x1b[0m" -#define _BLACK_(s) "\x1b[30m" s AEND #define _RED_(s) "\x1b[31m" s AEND #define _GREEN_(s) "\x1b[32m" s AEND #define _YELLOW_(s) "\x1b[33m" s AEND #define _BLUE_(s) "\x1b[34m" s AEND -#define _MAGENTA_(s) "\x1b[35m" s AEND #define _CYAN_(s) "\x1b[36m" s AEND -#define _WHITE_(s) "\x1b[37m" s AEND - -#define _BRIGHT_BLACK_(s) "\x1b[30;1m" s AEND -#define _BRIGHT_RED_(s) "\x1b[31;1m" s AEND -#define _BRIGHT_GREEN_(s) "\x1b[32;1m" s AEND -#define _BRIGHT_YELLOW_(s) "\x1b[33;1m" s AEND -#define _BRIGHT_BLUE_(s) "\x1b[34;1m" s AEND -#define _BRIGHT_MAGENTA_(s) "\x1b[35;1m" s AEND -#define _BRIGHT_CYAN_(s) "\x1b[36;1m" s AEND -#define _BRIGHT_WHITE_(s) "\x1b[37;1m" s AEND - -#define _BACK_BLACK_(s) "\x1b[40m" s AEND -#define _BACK_RED_(s) "\x1b[41m" s AEND -#define _BACK_GREEN_(s) "\x1b[42m" s AEND -#define _BACK_YELLOW_(s) "\x1b[43m" s AEND -#define _BACK_BLUE_(s) "\x1b[44m" s AEND -#define _BACK_MAGENTA_(s) "\x1b[45m" s AEND -#define _BACK_CYAN_(s) "\x1b[46m" s AEND -#define _BACK_WHITE_(s) "\x1b[47m" s AEND - -#define _BACK_BRIGHT_BLACK_(s) "\x1b[40;1m" s AEND -#define _BACK_BRIGHT_RED_(s) "\x1b[41;1m" s AEND -#define _BACK_BRIGHT_GREEN_(s) "\x1b[42;1m" s AEND -#define _BACK_BRIGHT_YELLOW_(s) "\x1b[43;1m" s AEND -#define _BACK_BRIGHT_BLUE_(s) "\x1b[44;1m" s AEND -#define _BACK_BRIGHT_MAGENTA_(s) "\x1b[45;1m" s AEND -#define _BACK_BRIGHT_CYAN_(s) "\x1b[46;1m" s AEND -#define _BACK_BRIGHT_WHITE_(s) "\x1b[47;1m" s AEND - -#define _CLEAR_ "\x1b[2J" -#define _CLEAR_SCROLLBACK_ "\x1b[3J" -#define _TOP_ "\x1b[1;1f" #if defined(HAVE_READLINE) // https://wiki.hackzine.org/development/misc/readline-color-prompt.html @@ -72,9 +38,4 @@ #define RL_ESC(a) a #endif // HAVE_READLINE -#define _RL_RED_(s) RL_ESC("\x1b[31m") s RL_ESC(AEND) -#define _RL_GREEN_(s) RL_ESC("\x1b[32m") s RL_ESC(AEND) -#define _RL_BOLD_RED_(s) RL_ESC("\x1b[1;31m") s RL_ESC(AEND) -#define _RL_BOLD_GREEN_(s) RL_ESC("\x1b[1;32m") s RL_ESC(AEND) - #endif diff --git a/HardNestedSolver/pm3/common.h b/HardNestedSolver/pm3/common.h index 55eab8a..60d1b61 100755 --- a/HardNestedSolver/pm3/common.h +++ b/HardNestedSolver/pm3/common.h @@ -22,7 +22,6 @@ #include #include #include -#include "pm3_cmd.h" // Packet structs #include "util.h" // FILE_PATH_SIZE #ifdef _WIN32 @@ -33,44 +32,6 @@ #define PATHSEP "/" #endif -// PM3 share path relative to executable when installed -#define PM3_SHARE_RELPATH ".." PATHSEP "share" PATHSEP "proxmark3" PATHSEP - -// PM3_USER_DIRECTORY will be expanded from $HOME, e.g. ~/.proxmark3/ -#define PM3_USER_DIRECTORY PATHSEP ".proxmark3" PATHSEP - -// PM3 subdirectories: -#define PYTHON_SCRIPTS_SUBDIR "pyscripts" PATHSEP -#define CMD_SCRIPTS_SUBDIR "cmdscripts" PATHSEP -#define DICTIONARIES_SUBDIR "dictionaries" PATHSEP -#define LUA_LIBRARIES_SUBDIR "lualibs" PATHSEP -#define LUA_SCRIPTS_SUBDIR "luascripts" PATHSEP -#define RESOURCES_SUBDIR "resources" PATHSEP -#define TRACES_SUBDIR "traces" PATHSEP -#define LOGS_SUBDIR "logs" PATHSEP -#define FIRMWARES_SUBDIR "firmware" PATHSEP -#define BOOTROM_SUBDIR "bootrom" PATHSEP "obj" PATHSEP -#define FULLIMAGE_SUBDIR "armsrc" PATHSEP "obj" PATHSEP - -#define PACKED __attribute__((packed)) - -#define VERSION_INFORMATION_MAGIC 0x56334d50 // "PM3V" - -// debug -#define DBG_NONE 0 // no messages -#define DBG_ERROR 1 // errors only -#define DBG_INFO 2 // errors + info messages -#define DBG_DEBUG 3 // errors + info + debug messages -#define DBG_EXTENDED 4 // errors + info + debug + breaking debug messages -extern int g_dbglevel; - -// tear-off -extern uint16_t g_tearoff_delay_us; -extern bool g_tearoff_enabled; - -// reader voltage field detector -#define MF_MINFIELDV 4000 - #ifndef MIN # define MIN(a, b) (((a) < (b)) ? (a) : (b)) #endif @@ -83,10 +44,6 @@ extern bool g_tearoff_enabled; # define ABS(a) ( ((a)<0) ? -(a) : (a) ) #endif - -//#define RAMFUNC __attribute((long_call, section(".ramfunc"))) -#define RAMFUNC __attribute((long_call, section(".ramfunc"))) __attribute__((target("arm"))) - #ifndef ROTR # define ROTR(x,n) (((uintmax_t)(x) >> (n)) | ((uintmax_t)(x) << ((sizeof(x) * 8) - (n)))) #endif @@ -173,25 +130,4 @@ extern bool g_tearoff_enabled; #ifndef SWAP_NIBBLE # define SWAP_NIBBLE(b) ( (NIBBLE_LOW(b)<< 4) | NIBBLE_HIGH(b)) #endif - -// Binary Encoded Digit -#ifndef BCD2DEC -# define BCD2DEC(bcd) HornerScheme(bcd, 0x10, 10) -#endif - -#ifndef DEC2BCD -# define DEC2BCD(dec) HornerScheme(dec, 10, 0x10) -#endif - -// bit stream operations -#define TEST_BIT(data, i) (*(data + (i / 8)) >> (7 - (i % 8))) & 1 -#define SET_BIT(data, i) *(data + (i / 8)) |= (1 << (7 - (i % 8))) -#define CLEAR_BIT(data, i) *(data + (i / 8)) &= ~(1 << (7 - (i % 8))) -#define FLIP_BIT(data, i) *(data + (i / 8)) ^= (1 << (7 - (i % 8))) - -typedef struct { - uint64_t Key[2]; - uint8_t foundKey[2]; -} sector_t; - #endif diff --git a/HardNestedSolver/pm3/commonutil.c b/HardNestedSolver/pm3/commonutil.c index f760784..1d9449e 100755 --- a/HardNestedSolver/pm3/commonutil.c +++ b/HardNestedSolver/pm3/commonutil.c @@ -16,97 +16,6 @@ // Utility functions used in many places, not specific to any piece of code. //----------------------------------------------------------------------------- #include "commonutil.h" -#include - -/* Similar to FpgaGatherVersion this formats stored version information - * into a string representation. It takes a pointer to the struct version_information_t, - * verifies the magic properties, then stores a formatted string, prefixed by - * prefix in dst. - */ -void FormatVersionInformation(char *dst, int len, const char *prefix, void *version_info) { - return; -} - -void format_version_information_short(char *dst, int len, void *version_info) { - return; -} - -/* - ref http://www.csm.ornl.gov/~dunigan/crc.html - Returns the value v with the bottom b [0,32] bits reflected. - Example: reflect(0x3e23L,3) == 0x3e26 -*/ -uint32_t reflect(uint32_t v, int b) { - uint32_t t = v; - for (int i = 0; i < b; ++i) { - if (t & 1) - v |= BITMASK((b - 1) - i); - else - v &= ~BITMASK((b - 1) - i); - t >>= 1; - } - return v; -} - -// https://graphics.stanford.edu/~seander/bithacks.html#BitReverseTable - -// Reverse the bits in a byte with 3 operations (64-bit multiply and modulus division): -uint8_t reflect8(uint8_t b) { - return (b * 0x0202020202ULL & 0x010884422010ULL) % 1023; -} - - -// Reverse the bits in a byte with 4 operations (64-bit multiply, no division): -/* -uint8_t reflect8(uint8_t b) { - return ((b * 0x80200802ULL) & 0x0884422110ULL) * 0x0101010101ULL >> 32; -} -*/ - -uint16_t reflect16(uint16_t b) { - uint16_t v = 0; - v |= (b & 0x8000) >> 15; - v |= (b & 0x4000) >> 13; - v |= (b & 0x2000) >> 11; - v |= (b & 0x1000) >> 9; - v |= (b & 0x0800) >> 7; - v |= (b & 0x0400) >> 5; - v |= (b & 0x0200) >> 3; - v |= (b & 0x0100) >> 1; - - v |= (b & 0x0080) << 1; - v |= (b & 0x0040) << 3; - v |= (b & 0x0020) << 5; - v |= (b & 0x0010) << 7; - v |= (b & 0x0008) << 9; - v |= (b & 0x0004) << 11; - v |= (b & 0x0002) << 13; - v |= (b & 0x0001) << 15; - return v; -} - -uint32_t reflect32(uint32_t b) { - // https://graphics.stanford.edu/~seander/bithacks.html#BitReverseTable - uint32_t v = b; // 32-bit word to reverse bit order - // swap odd and even bits - v = ((v >> 1) & 0x55555555) | ((v & 0x55555555) << 1); - // swap consecutive pairs - v = ((v >> 2) & 0x33333333) | ((v & 0x33333333) << 2); - // swap nibbles ... - v = ((v >> 4) & 0x0F0F0F0F) | ((v & 0x0F0F0F0F) << 4); - // swap bytes - v = ((v >> 8) & 0x00FF00FF) | ((v & 0x00FF00FF) << 8); - // swap 2-byte long pairs - v = (v >> 16) | (v << 16); - return v; -} - -void num_to_bytes(uint64_t n, size_t len, uint8_t *dest) { - while (len--) { - dest[len] = (uint8_t) n; - n >>= 8; - } -} uint64_t bytes_to_num(uint8_t *src, size_t len) { uint64_t num = 0; @@ -115,138 +24,4 @@ uint64_t bytes_to_num(uint8_t *src, size_t len) { src++; } return num; -} - -uint16_t MemLeToUint2byte(const uint8_t *data) { - return (data[1] << 8) + data[0]; -} - -uint32_t MemLeToUint3byte(const uint8_t *data) { - return (data[2] << 16) + (data[1] << 8) + data[0]; -} - -uint32_t MemLeToUint4byte(const uint8_t *data) { - return (data[3] << 24) + (data[2] << 16) + (data[1] << 8) + data[0]; -} - -uint16_t MemBeToUint2byte(const uint8_t *data) { - return (data[0] << 8) + data[1]; -} - -uint32_t MemBeToUint3byte(const uint8_t *data) { - return (data[0] << 16) + (data[1] << 8) + data[2]; -} - -uint32_t MemBeToUint4byte(const uint8_t *data) { - return (data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3]; -} - -void Uint2byteToMemLe(uint8_t *data, uint16_t value) { - data[1] = (value >> 8) & 0xff; - data[0] = value & 0xff; -} - -void Uint3byteToMemLe(uint8_t *data, uint32_t value) { - data[2] = (value >> 16) & 0xff; - data[1] = (value >> 8) & 0xff; - data[0] = value & 0xff; -} - -void Uint4byteToMemLe(uint8_t *data, uint32_t value) { - data[3] = (value >> 24) & 0xff; - data[2] = (value >> 16) & 0xff; - data[1] = (value >> 8) & 0xff; - data[0] = value & 0xff; -} - -void Uint2byteToMemBe(uint8_t *data, uint16_t value) { - data[0] = (value >> 8) & 0xff; - data[1] = value & 0xff; -} - -void Uint3byteToMemBe(uint8_t *data, uint32_t value) { - data[0] = (value >> 16) & 0xff; - data[1] = (value >> 8) & 0xff; - data[2] = value & 0xff; -} - -void Uint4byteToMemBe(uint8_t *data, uint32_t value) { - data[0] = (value >> 24) & 0xff; - data[1] = (value >> 16) & 0xff; - data[2] = (value >> 8) & 0xff; - data[3] = value & 0xff; -} - -// RotateLeft - Ultralight, Desfire -void rol(uint8_t *data, const size_t len) { - uint8_t first = data[0]; - for (size_t i = 0; i < len - 1; i++) { - data[i] = data[i + 1]; - } - data[len - 1] = first; -} - -void lsl(uint8_t *data, size_t len) { - for (size_t n = 0; n < len - 1; n++) { - data[n] = (data[n] << 1) | (data[n + 1] >> 7); - } - data[len - 1] <<= 1; -} - - -// BSWAP24 of array[3] -uint32_t le24toh(const uint8_t data[3]) { - return (data[2] << 16) | (data[1] << 8) | data[0]; -} - -// BSWAP24, take u32, output array -void htole24(uint32_t val, uint8_t data[3]) { - data[0] = (uint8_t) val; - data[1] = (uint8_t)(val >> 8); - data[2] = (uint8_t)(val >> 16); -} - - -// ROL on u32 -uint32_t rotl(uint32_t a, uint8_t n) { - n &= 31; - return (a << n) | (a >> (32 - n)); -} - -// ROR on u32 -uint32_t rotr(uint32_t a, uint8_t n) { - n &= 31; - return (a >> n) | (a << (32 - n)); -} - -uint16_t get_sw(const uint8_t *d, uint16_t n) { - if (n < 2) - return 0; - - n -= 2; - return (d[n] << 8 | d[n + 1]); -} - -// reverse same array -void reverse_array(uint8_t *d, size_t n) { - if (d == NULL || n < 2) { - return; - } - - for (int i = 0, j = n - 1; i < j; ++i, --j) { - d[i] ^= d[j]; - d[j] ^= d[i]; - d[i] ^= d[j]; - } -} - -// reverse src array into dest array -void reverse_array_copy(const uint8_t *src, int src_len, uint8_t *dest) { - if (src == NULL || src_len == 0 || dest == NULL) { - return; - } - - for (int i = 0; i < src_len; i++) { - dest[i] = src[(src_len - 1) - i]; - } -} +} \ No newline at end of file diff --git a/HardNestedSolver/pm3/commonutil.h b/HardNestedSolver/pm3/commonutil.h index 0332ac9..160f1a1 100755 --- a/HardNestedSolver/pm3/commonutil.h +++ b/HardNestedSolver/pm3/commonutil.h @@ -49,44 +49,6 @@ # define NTIME(n) for (int _index = 0; _index < n; _index++) #endif -void FormatVersionInformation(char *dst, int len, const char *prefix, void *version_info); -void format_version_information_short(char *dst, int len, void *version_info); - -uint32_t reflect(uint32_t v, int b); // used in crc.c ... -uint8_t reflect8(uint8_t b); // dedicated 8bit reversal -uint16_t reflect16(uint16_t b); // dedicated 16bit reversal -uint32_t reflect32(uint32_t b); // dedicated 32bit reversal - -void num_to_bytes(uint64_t n, size_t len, uint8_t *dest); uint64_t bytes_to_num(uint8_t *src, size_t len); -// LE and BE to/from memory -uint16_t MemLeToUint2byte(const uint8_t *data); -uint32_t MemLeToUint3byte(const uint8_t *data); -uint32_t MemLeToUint4byte(const uint8_t *data); -uint16_t MemBeToUint2byte(const uint8_t *data); -uint32_t MemBeToUint3byte(const uint8_t *data); -uint32_t MemBeToUint4byte(const uint8_t *data); -void Uint2byteToMemLe(uint8_t *data, uint16_t value); -void Uint3byteToMemLe(uint8_t *data, uint32_t value); -void Uint4byteToMemLe(uint8_t *data, uint32_t value); -void Uint2byteToMemBe(uint8_t *data, uint16_t value); -void Uint3byteToMemBe(uint8_t *data, uint32_t value); -void Uint4byteToMemBe(uint8_t *data, uint32_t value); - -// rotate left byte array -void rol(uint8_t *data, const size_t len); -void lsl(uint8_t *data, size_t len); -uint32_t le24toh(const uint8_t data[3]); -void htole24(uint32_t val, uint8_t data[3]); - -// rol on a u32 -uint32_t rotl(uint32_t a, uint8_t n); -uint32_t rotr(uint32_t a, uint8_t n); - -uint16_t get_sw(const uint8_t *d, uint16_t n); - -void reverse_array(uint8_t *d, size_t n); -void reverse_array_copy(const uint8_t *src, int src_len, uint8_t *dest); - #endif diff --git a/HardNestedSolver/pm3/comms.c b/HardNestedSolver/pm3/comms.c deleted file mode 100755 index dd57376..0000000 --- a/HardNestedSolver/pm3/comms.c +++ /dev/null @@ -1,909 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// See LICENSE.txt for the text of the license. -//----------------------------------------------------------------------------- -// Code for communicating with the proxmark3 hardware. -//----------------------------------------------------------------------------- - -#include "comms.h" - -#include -#include -#include -#include - -#include "uart/uart.h" -#include "ui.h" -#include "crc16.h" -#include "util.h" // g_pendingPrompt -#include "util_posix.h" // msclock -#include "util_darwin.h" // en/dis-ableNapp(); - -//#define COMMS_DEBUG -//#define COMMS_DEBUG_RAW - -// Serial port that we are communicating with the PM3 on. -static serial_port sp = NULL; - -communication_arg_t g_conn; -capabilities_t g_pm3_capabilities; - -static pthread_t communication_thread; -static bool comm_thread_dead = false; - -// Transmit buffer. -static PacketCommandOLD txBuffer; -static PacketCommandNGRaw txBufferNG; -static size_t txBufferNGLen; -static bool txBuffer_pending = false; -static pthread_mutex_t txBufferMutex = PTHREAD_MUTEX_INITIALIZER; -static pthread_cond_t txBufferSig = PTHREAD_COND_INITIALIZER; - -// Used by PacketResponseReceived as a ring buffer for messages that are yet to be -// processed by a command handler (WaitForResponse{,Timeout}) -static PacketResponseNG rxBuffer[CMD_BUFFER_SIZE]; - -// Points to the next empty position to write to -static int cmd_head = 0; - -// Points to the position of the last unread command -static int cmd_tail = 0; - -// to lock rxBuffer operations from different threads -static pthread_mutex_t rxBufferMutex = PTHREAD_MUTEX_INITIALIZER; - -// Global start time for WaitForResponseTimeout & dl_it, so we can reset timeout when we get packets -// as sending lot of these packets can slow down things wuite a lot on slow links (e.g. hw status or lf read at 9600) -static uint64_t timeout_start_time; - -static uint64_t last_packet_time; - -static bool dl_it(uint8_t *dest, uint32_t bytes, PacketResponseNG *response, size_t ms_timeout, bool show_warning, uint32_t rec_cmd); - -// Simple alias to track usages linked to the Bootloader, these commands must not be migrated. -// - commands sent to enter bootloader mode as we might have to talk to old firmwares -// - commands sent to the bootloader as it only supports OLD frames (which will always be the case for old BL) -void SendCommandBL(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len) { - SendCommandOLD(cmd, arg0, arg1, arg2, data, len); -} - -void SendCommandOLD(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len) { - PacketCommandOLD c = {CMD_UNKNOWN, {0, 0, 0}, {{0}}}; - c.cmd = cmd; - c.arg[0] = arg0; - c.arg[1] = arg1; - c.arg[2] = arg2; - if (len && data) - memcpy(&c.d, data, len); - -#ifdef COMMS_DEBUG - PrintAndLogEx(NORMAL, "Sending %s", "OLD"); -#endif -#ifdef COMMS_DEBUG_RAW - print_hex_break((uint8_t *)&c.cmd, sizeof(c.cmd), 32); - print_hex_break((uint8_t *)&c.arg, sizeof(c.arg), 32); - print_hex_break((uint8_t *)&c.d, sizeof(c.d), 32); -#endif - - if (!g_session.pm3_present) { - PrintAndLogEx(WARNING, "Sending bytes to Proxmark3 failed." _YELLOW_("offline")); - return; - } - - pthread_mutex_lock(&txBufferMutex); - /** - This causes hangups at times, when the pm3_old unit is unresponsive or disconnected. The main console thread is alive, - but comm thread just spins here. Not good.../holiman - **/ - while (txBuffer_pending) { - // wait for communication thread to complete sending a previous command - pthread_cond_wait(&txBufferSig, &txBufferMutex); - } - - txBuffer = c; - txBuffer_pending = true; - - // tell communication thread that a new command can be send - pthread_cond_signal(&txBufferSig); - - pthread_mutex_unlock(&txBufferMutex); - -//__atomic_test_and_set(&txcmd_pending, __ATOMIC_SEQ_CST); -} - -static void SendCommandNG_internal(uint16_t cmd, uint8_t *data, size_t len, bool ng) { -#ifdef COMMS_DEBUG - PrintAndLogEx(INFO, "Sending %s", ng ? "NG" : "MIX"); -#endif - - if (!g_session.pm3_present) { - PrintAndLogEx(INFO, "Sending bytes to proxmark failed - offline"); - return; - } - if (len > PM3_CMD_DATA_SIZE) { - PrintAndLogEx(WARNING, "Sending %zu bytes of payload is too much, abort", len); - return; - } - - PacketCommandNGPostamble *tx_post = (PacketCommandNGPostamble *)((uint8_t *)&txBufferNG + sizeof(PacketCommandNGPreamble) + len); - - pthread_mutex_lock(&txBufferMutex); - /** - This causes hangups at times, when the pm3_old unit is unresponsive or disconnected. The main console thread is alive, - but comm thread just spins here. Not good.../holiman - **/ - while (txBuffer_pending) { - // wait for communication thread to complete sending a previous command - pthread_cond_wait(&txBufferSig, &txBufferMutex); - } - - txBufferNG.pre.magic = COMMANDNG_PREAMBLE_MAGIC; - txBufferNG.pre.ng = ng; - txBufferNG.pre.length = len; - txBufferNG.pre.cmd = cmd; - if (len > 0 && data) - memcpy(&txBufferNG.data, data, len); - - if ((g_conn.send_via_fpc_usart && g_conn.send_with_crc_on_fpc) || ((!g_conn.send_via_fpc_usart) && g_conn.send_with_crc_on_usb)) { - uint8_t first, second; - compute_crc(CRC_14443_A, (uint8_t *)&txBufferNG, sizeof(PacketCommandNGPreamble) + len, &first, &second); - tx_post->crc = (first << 8) + second; - } else { - tx_post->crc = COMMANDNG_POSTAMBLE_MAGIC; - } - - txBufferNGLen = sizeof(PacketCommandNGPreamble) + len + sizeof(PacketCommandNGPostamble); - -#ifdef COMMS_DEBUG_RAW - print_hex_break((uint8_t *)&txBufferNG.pre, sizeof(PacketCommandNGPreamble), 32); - if (ng) { - print_hex_break((uint8_t *)&txBufferNG.data, len, 32); - } else { - print_hex_break((uint8_t *)&txBufferNG.data, 3 * sizeof(uint64_t), 32); - print_hex_break((uint8_t *)&txBufferNG.data + 3 * sizeof(uint64_t), len - 3 * sizeof(uint64_t), 32); - } - print_hex_break((uint8_t *)tx_post, sizeof(PacketCommandNGPostamble), 32); -#endif - txBuffer_pending = true; - - // tell communication thread that a new command can be send - pthread_cond_signal(&txBufferSig); - - pthread_mutex_unlock(&txBufferMutex); - -//__atomic_test_and_set(&txcmd_pending, __ATOMIC_SEQ_CST); -} - -void SendCommandNG(uint16_t cmd, uint8_t *data, size_t len) { - SendCommandNG_internal(cmd, data, len, true); -} - -void SendCommandMIX(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len) { - uint64_t arg[3] = {arg0, arg1, arg2}; - if (len > PM3_CMD_DATA_SIZE_MIX) { - PrintAndLogEx(WARNING, "Sending %zu bytes of payload is too much for MIX frames, abort", len); - return; - } - uint8_t cmddata[PM3_CMD_DATA_SIZE]; - memcpy(cmddata, arg, sizeof(arg)); - if (len && data) - memcpy(cmddata + sizeof(arg), data, len); - SendCommandNG_internal(cmd, cmddata, len + sizeof(arg), false); -} - - -/** - * @brief This method should be called when sending a new command to the pm3_old. In case any old - * responses from previous commands are stored in the buffer, a call to this method should clear them. - * A better method could have been to have explicit command-ACKS, so we can know which ACK goes to which - * operation. Right now we'll just have to live with this. - */ -void clearCommandBuffer(void) { - //This is a very simple operation - pthread_mutex_lock(&rxBufferMutex); - cmd_tail = cmd_head; - pthread_mutex_unlock(&rxBufferMutex); -} -/** - * @brief storeCommand stores a USB command in a circular buffer - * @param UC - */ -static void storeReply(PacketResponseNG *packet) { - pthread_mutex_lock(&rxBufferMutex); - if ((cmd_head + 1) % CMD_BUFFER_SIZE == cmd_tail) { - //If these two are equal, we're about to overwrite in the - // circular buffer. - PrintAndLogEx(FAILED, "WARNING: Command buffer about to overwrite command! This needs to be fixed!"); - fflush(stdout); - } - //Store the command at the 'head' location - PacketResponseNG *destination = &rxBuffer[cmd_head]; - memcpy(destination, packet, sizeof(PacketResponseNG)); - - //increment head and wrap - cmd_head = (cmd_head + 1) % CMD_BUFFER_SIZE; - pthread_mutex_unlock(&rxBufferMutex); -} -/** - * @brief getCommand gets a command from an internal circular buffer. - * @param response location to write command - * @return 1 if response was returned, 0 if nothing has been received - */ -static int getReply(PacketResponseNG *packet) { - pthread_mutex_lock(&rxBufferMutex); - //If head == tail, there's nothing to read, or if we just got initialized - if (cmd_head == cmd_tail) { - pthread_mutex_unlock(&rxBufferMutex); - return 0; - } - - //Pick out the next unread command - memcpy(packet, &rxBuffer[cmd_tail], sizeof(PacketResponseNG)); - - //Increment tail - this is a circular buffer, so modulo buffer size - cmd_tail = (cmd_tail + 1) % CMD_BUFFER_SIZE; - - pthread_mutex_unlock(&rxBufferMutex); - return 1; -} - -//----------------------------------------------------------------------------- -// Entry point into our code: called whenever we received a packet over USB -// that we weren't necessarily expecting, for example a debug print. -//----------------------------------------------------------------------------- -static void PacketResponseReceived(PacketResponseNG *packet) { - - // we got a packet, reset WaitForResponseTimeout timeout - uint64_t prev_clk = __atomic_load_n(&last_packet_time, __ATOMIC_SEQ_CST); - uint64_t clk = msclock(); - __atomic_store_n(&timeout_start_time, clk, __ATOMIC_SEQ_CST); - __atomic_store_n(&last_packet_time, clk, __ATOMIC_SEQ_CST); - (void) prev_clk; -// PrintAndLogEx(NORMAL, "[%07"PRIu64"] RECV %s magic %08x length %04x status %04x crc %04x cmd %04x", -// clk - prev_clk, packet->ng ? "NG" : "OLD", packet->magic, packet->length, packet->status, packet->crc, packet->cmd); - - switch (packet->cmd) { - // First check if we are handling a debug message - case CMD_DEBUG_PRINT_STRING: { - - char s[PM3_CMD_DATA_SIZE + 1]; - memset(s, 0x00, sizeof(s)); - - size_t len; - uint16_t flag; - if (packet->ng) { - struct d { - uint16_t flag; - uint8_t buf[PM3_CMD_DATA_SIZE - sizeof(uint16_t)]; - } PACKED; - struct d *data = (struct d *)&packet->data.asBytes; - len = packet->length - sizeof(data->flag); - flag = data->flag; - memcpy(s, data->buf, len); - } else { - len = MIN(packet->oldarg[0], PM3_CMD_DATA_SIZE); - flag = packet->oldarg[1]; - memcpy(s, packet->data.asBytes, len); - } - - if (flag & FLAG_LOG) { - if (g_pendingPrompt) { - PrintAndLogEx(NORMAL, ""); - g_pendingPrompt = false; - } - //PrintAndLogEx(NORMAL, "[" _MAGENTA_("pm3_old") "] ["_BLUE_("#")"] " "%s", s); - PrintAndLogEx(NORMAL, "[" _BLUE_("#") "] %s", s); - } else { - if (flag & FLAG_INPLACE) - PrintAndLogEx(NORMAL, "\r" NOLF); - - PrintAndLogEx(NORMAL, "%s" NOLF, s); - - if (flag & FLAG_NEWLINE) - PrintAndLogEx(NORMAL, ""); - } - break; - } - case CMD_DEBUG_PRINT_INTEGERS: { - if (packet->ng == false) - PrintAndLogEx(NORMAL, "[" _MAGENTA_("pm3_old") "] ["_BLUE_("#")"] " "%" PRIx64 ", %" PRIx64 ", %" PRIx64 "", packet->oldarg[0], packet->oldarg[1], packet->oldarg[2]); - break; - } - // iceman: hw status - down the path on device, runs printusbspeed which starts sending a lot of - // CMD_DOWNLOAD_BIGBUF packages which is not dealt with. I wonder if simply ignoring them will - // work. lets try it. - default: { - storeReply(packet); - break; - } - } -} - - -// The communications thread. -// signals to main thread when a response is ready to process. -// -static void -#ifdef __has_attribute -#if __has_attribute(force_align_arg_pointer) -__attribute__((force_align_arg_pointer)) -#endif -#endif -*uart_communication(void *targ) { - communication_arg_t *connection = (communication_arg_t *)targ; - uint32_t rxlen; - bool commfailed = false; - PacketResponseNG rx; - PacketResponseNGRaw rx_raw; - -#if defined(__MACH__) && defined(__APPLE__) - disableAppNap("Proxmark3 polling UART"); -#endif - - // is this connection->run a cross thread call? - while (connection->run) { - rxlen = 0; - bool ACK_received = false; - bool error = false; - int res; - - // Signal to main thread that communications seems off. - // main thread will kill and restart this thread. - if (commfailed) { - if (g_conn.last_command != CMD_HARDWARE_RESET) { - PrintAndLogEx(WARNING, "\nCommunicating with Proxmark3 device " _RED_("failed")); - } - __atomic_test_and_set(&comm_thread_dead, __ATOMIC_SEQ_CST); - break; - } - - res = uart_receive(sp, (uint8_t *)&rx_raw.pre, sizeof(PacketResponseNGPreamble), &rxlen); - if ((res == PM3_SUCCESS) && (rxlen == sizeof(PacketResponseNGPreamble))) { - rx.magic = rx_raw.pre.magic; - uint16_t length = rx_raw.pre.length; - rx.ng = rx_raw.pre.ng; - rx.status = rx_raw.pre.status; - rx.cmd = rx_raw.pre.cmd; - if (rx.magic == RESPONSENG_PREAMBLE_MAGIC) { // New style NG reply - if (length > PM3_CMD_DATA_SIZE) { - PrintAndLogEx(WARNING, "Received packet frame with incompatible length: 0x%04x", length); - error = true; - } - if ((!error) && (length > 0)) { // Get the variable length payload - - res = uart_receive(sp, (uint8_t *)&rx_raw.data, length, &rxlen); - if ((res != PM3_SUCCESS) || (rxlen != length)) { - PrintAndLogEx(WARNING, "Received packet frame with variable part too short? %d/%d", rxlen, length); - error = true; - } else { - - if (rx.ng) { // Received a valid NG frame - memcpy(&rx.data, &rx_raw.data, length); - rx.length = length; - if ((rx.cmd == g_conn.last_command) && (rx.status == PM3_SUCCESS)) { - ACK_received = true; - } - } else { - uint64_t arg[3]; - if (length < sizeof(arg)) { - PrintAndLogEx(WARNING, "Received MIX packet frame with incompatible length: 0x%04x", length); - error = true; - } - if (!error) { // Received a valid MIX frame - memcpy(arg, &rx_raw.data, sizeof(arg)); - rx.oldarg[0] = arg[0]; - rx.oldarg[1] = arg[1]; - rx.oldarg[2] = arg[2]; - memcpy(&rx.data, ((uint8_t *)&rx_raw.data) + sizeof(arg), length - sizeof(arg)); - rx.length = length - sizeof(arg); - if (rx.cmd == CMD_ACK) { - ACK_received = true; - } - } - } - } - } else if ((!error) && (length == 0)) { // we received an empty frame - if (rx.ng) - rx.length = 0; // set received length to 0 - else { // old frames can't be empty - PrintAndLogEx(WARNING, "Received empty MIX packet frame (length: 0x00)"); - - error = true; - } - } - if (!error) { // Get the postamble - res = uart_receive(sp, (uint8_t *)&rx_raw.foopost, sizeof(PacketResponseNGPostamble), &rxlen); - if ((res != PM3_SUCCESS) || (rxlen != sizeof(PacketResponseNGPostamble))) { - PrintAndLogEx(WARNING, "Received packet frame without postamble"); - error = true; - } - } - if (!error) { // Check CRC, accept MAGIC as placeholder - rx.crc = rx_raw.foopost.crc; - if (rx.crc != RESPONSENG_POSTAMBLE_MAGIC) { - uint8_t first, second; - compute_crc(CRC_14443_A, (uint8_t *)&rx_raw, sizeof(PacketResponseNGPreamble) + length, &first, &second); - if ((first << 8) + second != rx.crc) { - PrintAndLogEx(WARNING, "Received packet frame with invalid CRC %02X%02X <> %04X", first, second, rx.crc); - error = true; - } - } - } - if (!error) { // Received a valid OLD frame -#ifdef COMMS_DEBUG - PrintAndLogEx(NORMAL, "Receiving %s:", rx.ng ? "NG" : "MIX"); -#endif -#ifdef COMMS_DEBUG_RAW - print_hex_break((uint8_t *)&rx_raw.pre, sizeof(PacketResponseNGPreamble), 32); - print_hex_break((uint8_t *)&rx_raw.data, rx_raw.pre.length, 32); - print_hex_break((uint8_t *)&rx_raw.foopost, sizeof(PacketResponseNGPostamble), 32); -#endif - PacketResponseReceived(&rx); - } - } else { // Old style reply - PacketResponseOLD rx_old; - memcpy(&rx_old, &rx_raw.pre, sizeof(PacketResponseNGPreamble)); - - res = uart_receive(sp, ((uint8_t *)&rx_old) + sizeof(PacketResponseNGPreamble), sizeof(PacketResponseOLD) - sizeof(PacketResponseNGPreamble), &rxlen); - if ((res != PM3_SUCCESS) || (rxlen != sizeof(PacketResponseOLD) - sizeof(PacketResponseNGPreamble))) { - PrintAndLogEx(WARNING, "Received packet OLD frame with payload too short? %d/%zu", rxlen, sizeof(PacketResponseOLD) - sizeof(PacketResponseNGPreamble)); - error = true; - } - if (!error) { -#ifdef COMMS_DEBUG - PrintAndLogEx(NORMAL, "Receiving OLD:"); -#endif -#ifdef COMMS_DEBUG_RAW - print_hex_break((uint8_t *)&rx_old.cmd, sizeof(rx_old.cmd), 32); - print_hex_break((uint8_t *)&rx_old.arg, sizeof(rx_old.arg), 32); - print_hex_break((uint8_t *)&rx_old.d, sizeof(rx_old.d), 32); -#endif - rx.ng = false; - rx.magic = 0; - rx.status = 0; - rx.crc = 0; - rx.cmd = rx_old.cmd; - rx.oldarg[0] = rx_old.arg[0]; - rx.oldarg[1] = rx_old.arg[1]; - rx.oldarg[2] = rx_old.arg[2]; - rx.length = PM3_CMD_DATA_SIZE; - memcpy(&rx.data, &rx_old.d, rx.length); - PacketResponseReceived(&rx); - if (rx.cmd == CMD_ACK) { - ACK_received = true; - } - } - } - } else { - if (rxlen > 0) { - PrintAndLogEx(WARNING, "Received packet frame preamble too short: %d/%zu", rxlen, sizeof(PacketResponseNGPreamble)); - error = true; - } - if (res == PM3_ENOTTY) { - commfailed = true; - } - } - - // TODO if error, shall we resync ? - - pthread_mutex_lock(&txBufferMutex); - - if (connection->block_after_ACK) { - // if we just received an ACK, wait here until a new command is to be transmitted - // This is only working on OLD frames, and only used by flasher and flashmem - if (ACK_received) { -#ifdef COMMS_DEBUG - PrintAndLogEx(NORMAL, "Received ACK, fast TX mode: ignoring other RX till TX"); -#endif - while (!txBuffer_pending) { - pthread_cond_wait(&txBufferSig, &txBufferMutex); - } - } - } - - if (txBuffer_pending) { - - if (txBufferNGLen) { // NG packet - res = uart_send(sp, (uint8_t *) &txBufferNG, txBufferNGLen); - if (res == PM3_EIO) { - commfailed = true; - } - g_conn.last_command = txBufferNG.pre.cmd; - txBufferNGLen = 0; - } else { - res = uart_send(sp, (uint8_t *) &txBuffer, sizeof(PacketCommandOLD)); - if (res == PM3_EIO) { - commfailed = true; - } - g_conn.last_command = txBuffer.cmd; - } - - txBuffer_pending = false; - - // main thread doesn't know send failed... - - // tell main thread that txBuffer is empty - pthread_cond_signal(&txBufferSig); - } - - pthread_mutex_unlock(&txBufferMutex); - } - - // when thread dies, we close the serial port. - uart_close(sp); - sp = NULL; - -#if defined(__MACH__) && defined(__APPLE__) - enableAppNap(); -#endif - - pthread_exit(NULL); - return NULL; -} - -bool IsCommunicationThreadDead(void) { - bool ret = __atomic_load_n(&comm_thread_dead, __ATOMIC_SEQ_CST); - return ret; -} - -bool OpenProxmark(pm3_device_t **dev, const char *port, bool wait_for_port, int timeout, bool flash_mode, uint32_t speed) { - - if (!wait_for_port) { - PrintAndLogEx(INFO, "Using UART port " _YELLOW_("%s"), port); - sp = uart_open(port, speed); - } else { - PrintAndLogEx(SUCCESS, "Waiting for Proxmark3 to appear on " _YELLOW_("%s"), port); - fflush(stdout); - int openCount = 0; - PrintAndLogEx(INPLACE, "% 3i", timeout); - do { - sp = uart_open(port, speed); - msleep(500); - PrintAndLogEx(INPLACE, "% 3i", timeout - openCount - 1); - - } while (++openCount < timeout && (sp == INVALID_SERIAL_PORT || sp == CLAIMED_SERIAL_PORT)); - } - - // check result of uart opening - if (sp == INVALID_SERIAL_PORT) { - PrintAndLogEx(WARNING, "\n" _RED_("ERROR:") " invalid serial port " _YELLOW_("%s"), port); - PrintAndLogEx(HINT, "Try the shell script " _YELLOW_("`./pm3_old --list`") " to get a list of possible serial ports"); - sp = NULL; - return false; - } else if (sp == CLAIMED_SERIAL_PORT) { - PrintAndLogEx(WARNING, "\n" _RED_("ERROR:") " serial port " _YELLOW_("%s") " is claimed by another process", port); - PrintAndLogEx(HINT, "Try the shell script " _YELLOW_("`./pm3_old --list`") " to get a list of possible serial ports"); - - sp = NULL; - return false; - } else { - // start the communication thread - if (port != g_conn.serial_port_name) { - uint16_t len = MIN(strlen(port), FILE_PATH_SIZE - 1); - memset(g_conn.serial_port_name, 0, FILE_PATH_SIZE); - memcpy(g_conn.serial_port_name, port, len); - } - g_conn.run = true; - g_conn.block_after_ACK = flash_mode; - // Flags to tell where to add CRC on sent replies - g_conn.send_with_crc_on_usb = false; - g_conn.send_with_crc_on_fpc = true; - // "Session" flag, to tell via which interface next msgs should be sent: USB or FPC USART - g_conn.send_via_fpc_usart = false; - - pthread_create(&communication_thread, NULL, &uart_communication, &g_conn); - __atomic_clear(&comm_thread_dead, __ATOMIC_SEQ_CST); - g_session.pm3_present = true; // TODO support for multiple devices - - fflush(stdout); - if (*dev == NULL) { - *dev = calloc(sizeof(pm3_device_t), sizeof(uint8_t)); - } - (*dev)->g_conn = &g_conn; // TODO g_conn shouldn't be global - return true; - } -} - -// check if we can communicate with Pm3 -int TestProxmark(pm3_device_t *dev) { - - PacketResponseNG resp; - uint16_t len = 32; - uint8_t data[len]; - for (uint16_t i = 0; i < len; i++) - data[i] = i & 0xFF; - - __atomic_store_n(&last_packet_time, msclock(), __ATOMIC_SEQ_CST); - clearCommandBuffer(); - SendCommandNG(CMD_PING, data, len); - - uint32_t timeout; - -#ifdef USART_SLOW_LINK - // 10s timeout for slow FPC, e.g. over BT - // as this is the very first command sent to the pm3_old - // that initiates the BT connection - timeout = 10000; -#else - timeout = 1000; -#endif - - if (WaitForResponseTimeoutW(CMD_PING, &resp, timeout, false) == 0) { - return PM3_ETIMEOUT; - } - - bool error = memcmp(data, resp.data.asBytes, len) != 0; - if (error) { - return PM3_EIO; - } - - SendCommandNG(CMD_CAPABILITIES, NULL, 0); - if (WaitForResponseTimeoutW(CMD_CAPABILITIES, &resp, 1000, false) == 0) { - return PM3_ETIMEOUT; - } - - if ((resp.length != sizeof(g_pm3_capabilities)) || (resp.data.asBytes[0] != CAPABILITIES_VERSION)) { - PrintAndLogEx(ERR, _RED_("Capabilities structure version sent by Proxmark3 is not the same as the one used by the client!")); - PrintAndLogEx(ERR, _RED_("Please flash the Proxmark with the same version as the client.")); - return PM3_EDEVNOTSUPP; - } - - memcpy(&g_pm3_capabilities, resp.data.asBytes, MIN(sizeof(capabilities_t), resp.length)); - g_conn.send_via_fpc_usart = g_pm3_capabilities.via_fpc; - g_conn.uart_speed = g_pm3_capabilities.baudrate; - - PrintAndLogEx(INFO, "Communicating with PM3 over %s%s%s", - g_conn.send_via_fpc_usart ? _YELLOW_("FPC UART") : _YELLOW_("USB-CDC"), - memcmp(g_conn.serial_port_name, "tcp:", 4) == 0 ? " over " _YELLOW_("TCP") : "", - memcmp(g_conn.serial_port_name, "bt:", 3) == 0 ? " over " _YELLOW_("BT") : ""); - - if (g_conn.send_via_fpc_usart) { - PrintAndLogEx(INFO, "PM3 UART serial baudrate: " _YELLOW_("%u") "\n", g_conn.uart_speed); - } else { - int res = uart_reconfigure_timeouts(UART_USB_CLIENT_RX_TIMEOUT_MS); - if (res != PM3_SUCCESS) { - return res; - } - } - return PM3_SUCCESS; -} - -void CloseProxmark(pm3_device_t *dev) { - dev->g_conn->run = false; - -#ifdef __BIONIC__ - if (communication_thread != 0) { - pthread_join(communication_thread, NULL); - } -#else - pthread_join(communication_thread, NULL); -#endif - - if (sp) { - uart_close(sp); - } - - // Clean up our state - sp = NULL; -#ifdef __BIONIC__ - if (communication_thread != 0) { - memset(&communication_thread, 0, sizeof(pthread_t)); - } -#else - memset(&communication_thread, 0, sizeof(pthread_t)); -#endif - - g_session.pm3_present = false; -} - -// Gives a rough estimate of the communication delay based on channel & baudrate -// Max communication delay is when sending largest frame and receiving largest frame -// Empirical measures on FTDI with physical cable: -// "hw pingng 512" -// usb -> 6..32ms -// 460800 -> 40..70ms -// 9600 -> 1100..1150ms -// ~ = 12000000 / USART_BAUD_RATE -// Let's take 2x (maybe we need more for BT link?) -static size_t communication_delay(void) { - if (g_conn.send_via_fpc_usart) // needed also for Windows USB USART?? - return 2 * (12000000 / g_conn.uart_speed); - return 0; -} - -/** - * @brief Waits for a certain response type. This method waits for a maximum of - * ms_timeout milliseconds for a specified response command. - - * @param cmd command to wait for, or CMD_UNKNOWN to take any command. - * @param response struct to copy received command into. - * @param ms_timeout display message after 3 seconds - * @param show_warning display message after 3 seconds - * @return true if command was returned, otherwise false - */ -bool WaitForResponseTimeoutW(uint32_t cmd, PacketResponseNG *response, size_t ms_timeout, bool show_warning) { - - PacketResponseNG resp; - - if (response == NULL) - response = &resp; - - // Add delay depending on the communication channel & speed - if (ms_timeout != (size_t) - 1) - ms_timeout += communication_delay(); - - __atomic_store_n(&timeout_start_time, msclock(), __ATOMIC_SEQ_CST); - - // Wait until the command is received - while (true) { - - while (getReply(response)) { - if (cmd == CMD_UNKNOWN || response->cmd == cmd) { - return true; - } - if (response->cmd == CMD_WTX && response->length == sizeof(uint16_t)) { - uint16_t wtx = response->data.asDwords[0] & 0xFFFF; - PrintAndLogEx(DEBUG, "Got Waiting Time eXtension request %i ms", wtx); - if (ms_timeout != (size_t) - 1) - ms_timeout += wtx; - } - } - - uint64_t tmp_clk = __atomic_load_n(&timeout_start_time, __ATOMIC_SEQ_CST); - if ((ms_timeout != (size_t) - 1) && (msclock() - tmp_clk > ms_timeout)) - break; - - if (msclock() - tmp_clk > 3000 && show_warning) { - // 3 seconds elapsed (but this doesn't mean the timeout was exceeded) -// PrintAndLogEx(INFO, "Waiting for a response from the Proxmark3..."); - PrintAndLogEx(INFO, "You can cancel this operation by pressing the pm3_old button"); - show_warning = false; - } - // just to avoid CPU busy loop: - msleep(10); - } - return false; -} - -bool WaitForResponseTimeout(uint32_t cmd, PacketResponseNG *response, size_t ms_timeout) { - return WaitForResponseTimeoutW(cmd, response, ms_timeout, true); -} - -bool WaitForResponse(uint32_t cmd, PacketResponseNG *response) { - return WaitForResponseTimeoutW(cmd, response, -1, true); -} - -/** -* Data transfer from Proxmark to client. This method times out after -* ms_timeout milliseconds. -* @brief GetFromDevice -* @param memtype Type of memory to download from proxmark -* @param dest Destination address for transfer -* @param bytes number of bytes to be transferred -* @param start_index offset into Proxmark3 BigBuf[] -* @param data used by SPIFFS to provide filename -* @param datalen used by SPIFFS to provide filename length -* @param response struct to copy last command (CMD_ACK) into -* @param ms_timeout timeout in milliseconds -* @param show_warning display message after 2 seconds -* @return true if command was returned, otherwise false -*/ -bool GetFromDevice(DeviceMemType_t memtype, uint8_t *dest, uint32_t bytes, uint32_t start_index, uint8_t *data, uint32_t datalen, PacketResponseNG *response, size_t ms_timeout, bool show_warning) { - - if (dest == NULL) return false; - if (bytes == 0) return true; - - PacketResponseNG resp; - if (response == NULL) - response = &resp; - - // clear - clearCommandBuffer(); - - switch (memtype) { - case BIG_BUF: { - SendCommandMIX(CMD_DOWNLOAD_BIGBUF, start_index, bytes, 0, NULL, 0); - return dl_it(dest, bytes, response, ms_timeout, show_warning, CMD_DOWNLOADED_BIGBUF); - } - case BIG_BUF_EML: { - SendCommandMIX(CMD_DOWNLOAD_EML_BIGBUF, start_index, bytes, 0, NULL, 0); - return dl_it(dest, bytes, response, ms_timeout, show_warning, CMD_DOWNLOADED_EML_BIGBUF); - } - case SPIFFS: { - SendCommandMIX(CMD_SPIFFS_DOWNLOAD, start_index, bytes, 0, data, datalen); - return dl_it(dest, bytes, response, ms_timeout, show_warning, CMD_SPIFFS_DOWNLOADED); - } - case FLASH_MEM: { - SendCommandMIX(CMD_FLASHMEM_DOWNLOAD, start_index, bytes, 0, NULL, 0); - return dl_it(dest, bytes, response, ms_timeout, show_warning, CMD_FLASHMEM_DOWNLOADED); - } - case SIM_MEM: { - //SendCommandMIX(CMD_DOWNLOAD_SIM_MEM, start_index, bytes, 0, NULL, 0); - //return dl_it(dest, bytes, response, ms_timeout, show_warning, CMD_DOWNLOADED_SIMMEM); - return false; - } - case FPGA_MEM: { - SendCommandNG(CMD_FPGAMEM_DOWNLOAD, NULL, 0); - return dl_it(dest, bytes, response, ms_timeout, show_warning, CMD_FPGAMEM_DOWNLOADED); - } - } - return false; -} - -static bool dl_it(uint8_t *dest, uint32_t bytes, PacketResponseNG *response, size_t ms_timeout, bool show_warning, uint32_t rec_cmd) { - - uint32_t bytes_completed = 0; - __atomic_store_n(&timeout_start_time, msclock(), __ATOMIC_SEQ_CST); - - // Add delay depending on the communication channel & speed - if (ms_timeout != (size_t) - 1) - ms_timeout += communication_delay(); - - while (true) { - - if (getReply(response)) { - - if (response->cmd == CMD_ACK) - return true; - if (response->cmd == CMD_SPIFFS_DOWNLOAD && response->status == PM3_EMALLOC) - return false; - // Spiffs // fpgamem-plot download is converted to NG, - if (response->cmd == CMD_SPIFFS_DOWNLOAD || response->cmd == CMD_FPGAMEM_DOWNLOAD) - return true; - - // sample_buf is a array pointer, located in data.c - // arg0 = offset in transfer. Startindex of this chunk - // arg1 = length bytes to transfer - // arg2 = bigbuff tracelength (?) - if (response->cmd == rec_cmd) { - - uint32_t offset = response->oldarg[0]; - uint32_t copy_bytes = MIN(bytes - bytes_completed, response->oldarg[1]); - //uint32_t tracelen = response->oldarg[2]; - - // extended bounds check1. upper limit is PM3_CMD_DATA_SIZE - // shouldn't happen - copy_bytes = MIN(copy_bytes, PM3_CMD_DATA_SIZE); - - // extended bounds check2. - if (offset + copy_bytes > bytes) { - PrintAndLogEx(FAILED, "ERROR: Out of bounds when downloading from device, offset %u | len %u | total len %u > buf_size %u", offset, copy_bytes, offset + copy_bytes, bytes); - break; - } - - memcpy(dest + offset, response->data.asBytes, copy_bytes); - bytes_completed += copy_bytes; - } else if (response->cmd == CMD_WTX && response->length == sizeof(uint16_t)) { - uint16_t wtx = response->data.asDwords[0] & 0xFFFF; - PrintAndLogEx(DEBUG, "Got Waiting Time eXtension request %i ms", wtx); - if (ms_timeout != (size_t) - 1) - ms_timeout += wtx; - } - } - - uint64_t tmp_clk = __atomic_load_n(&timeout_start_time, __ATOMIC_SEQ_CST); - if (msclock() - tmp_clk > ms_timeout) { - PrintAndLogEx(FAILED, "Timed out while trying to download data from device"); - break; - } - - if (msclock() - tmp_clk > 3000 && show_warning) { - // 3 seconds elapsed (but this doesn't mean the timeout was exceeded) - PrintAndLogEx(INFO, "Waiting for a response from the Proxmark3..."); - PrintAndLogEx(INFO, "You can cancel this operation by pressing the pm3_old button"); - show_warning = false; - } - } - return false; -} diff --git a/HardNestedSolver/pm3/comms.h b/HardNestedSolver/pm3/comms.h deleted file mode 100755 index 6eaffcb..0000000 --- a/HardNestedSolver/pm3/comms.h +++ /dev/null @@ -1,83 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// See LICENSE.txt for the text of the license. -//----------------------------------------------------------------------------- -// Code for communicating with the Proxmark3 hardware. -//----------------------------------------------------------------------------- - -#ifndef COMMS_H_ -#define COMMS_H_ - -#include "common.h" -#include "pm3_cmd.h" // Packet structs -#include "util.h" // FILE_PATH_SIZE - -#ifdef __cplusplus -extern "C" { -#endif - -//For storing command that are received from the device -#ifndef CMD_BUFFER_SIZE -#define CMD_BUFFER_SIZE 100 -#endif - -typedef enum { - BIG_BUF, - BIG_BUF_EML, - FLASH_MEM, - SIM_MEM, - SPIFFS, - FPGA_MEM, -} DeviceMemType_t; - -typedef struct { - bool run; // If TRUE, continue running the uart_communication thread - bool block_after_ACK; // if true, block after receiving an ACK package - // Flags to tell where to add CRC on sent replies - bool send_with_crc_on_usb; - bool send_with_crc_on_fpc; - // "Session" flag, to tell via which interface next msgs are sent: USB or FPC USART - bool send_via_fpc_usart; - // To memorise baudrate - uint32_t uart_speed; - uint16_t last_command; - char serial_port_name[FILE_PATH_SIZE]; -} communication_arg_t; - -extern communication_arg_t g_conn; - -typedef struct pm3_device { - communication_arg_t *g_conn; - int script_embedded; -} pm3_device_t; - -void *uart_receiver(void *targ); -void SendCommandBL(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len); -void SendCommandOLD(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len); -void SendCommandNG(uint16_t cmd, uint8_t *data, size_t len); -void SendCommandMIX(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len); -void clearCommandBuffer(void); - -#define FLASHMODE_SPEED 460800 -bool IsCommunicationThreadDead(void); -bool OpenProxmark(pm3_device_t **dev, const char *port, bool wait_for_port, int timeout, bool flash_mode, uint32_t speed); -int TestProxmark(pm3_device_t *dev); -void CloseProxmark(pm3_device_t *dev); - -#ifdef __cplusplus -} -#endif -#endif - - diff --git a/HardNestedSolver/pm3/crc.c b/HardNestedSolver/pm3/crc.c deleted file mode 100755 index 016d8e5..0000000 --- a/HardNestedSolver/pm3/crc.c +++ /dev/null @@ -1,181 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// See LICENSE.txt for the text of the license. -//----------------------------------------------------------------------------- -// Generic CRC calculation code. -//----------------------------------------------------------------------------- -// the Check value below in the comments is CRC of the string '123456789' -// -#include "crc.h" - -#include "commonutil.h" - -void crc_init_ref(crc_t *crc, int order, uint32_t polynom, uint32_t initial_value, uint32_t final_xor, bool refin, bool refout) { - crc_init(crc, order, polynom, initial_value, final_xor); - crc->refin = refin; - crc->refout = refout; - crc_clear(crc); -} - -void crc_init(crc_t *crc, int order, uint32_t polynom, uint32_t initial_value, uint32_t final_xor) { - crc->order = order; - crc->topbit = BITMASK(order - 1); - crc->polynom = polynom; - crc->initial_value = initial_value; - crc->final_xor = final_xor; - crc->mask = (1L << order) - 1; - crc->refin = false; - crc->refout = false; - crc_clear(crc); -} - -void crc_clear(crc_t *crc) { - - crc->state = crc->initial_value & crc->mask; - if (crc->refin) - crc->state = reflect(crc->state, crc->order); -} - -void crc_update2(crc_t *crc, uint32_t data, int data_width) { - - if (crc->refin) - data = reflect(data, data_width); - - // Bring the next byte into the remainder. - crc->state ^= data << (crc->order - data_width); - - for (uint8_t bit = data_width; bit > 0; --bit) { - - if (crc->state & crc->topbit) - crc->state = (crc->state << 1) ^ crc->polynom; - else - crc->state = (crc->state << 1); - } -} - -void crc_update(crc_t *crc, uint32_t data, int data_width) { - if (crc->refin) - data = reflect(data, data_width); - - int i; - for (i = 0; i < data_width; i++) { - int oldstate = crc->state; - crc->state = crc->state >> 1; - if ((oldstate ^ data) & 1) { - crc->state ^= crc->polynom; - } - data >>= 1; - } -} - -uint32_t crc_finish(crc_t *crc) { - uint32_t val = crc->state; - if (crc->refout) - val = reflect(val, crc->order); - return (val ^ crc->final_xor) & crc->mask; -} - -/* -static void print_crc(crc_t *crc) { - printf(" Order %d\n Poly %x\n Init %x\n Final %x\n Mask %x\n topbit %x\n RefIn %s\n RefOut %s\n State %x\n", - crc->order, - crc->polynom, - crc->initial_value, - crc->final_xor, - crc->mask, - crc->topbit, - (crc->refin) ? "TRUE":"FALSE", - (crc->refout) ? "TRUE":"FALSE", - crc->state - ); -} -*/ - -// width=8 poly=0x31 init=0x00 refin=true refout=true xorout=0x00 check=0xA1 name="CRC-8/MAXIM" -uint32_t CRC8Maxim(uint8_t *buff, size_t size) { - crc_t crc; - crc_init_ref(&crc, 8, 0x31, 0, 0, true, true); - for (size_t i = 0; i < size; ++i) { - crc_update2(&crc, buff[i], 8); - } - return crc_finish(&crc); -} -// width=8 poly=0x1d, init=0xc7 (0xe3 - WRONG! but it mentioned in MAD datasheet) refin=false refout=false xorout=0x00 name="CRC-8/MIFARE-MAD" -uint32_t CRC8Mad(uint8_t *buff, size_t size) { - crc_t crc; - crc_init_ref(&crc, 8, 0x1d, 0xc7, 0, false, false); - for (size_t i = 0; i < size; ++i) { - crc_update2(&crc, buff[i], 8); - } - return crc_finish(&crc); -} -// width=4 poly=0xC, reversed poly=0x7 init=0x5 refin=true refout=true xorout=0x0000 check= name="CRC-4/LEGIC" -uint32_t CRC4Legic(uint8_t *buff, size_t size) { - crc_t crc; - crc_init_ref(&crc, 4, 0x19 >> 1, 0x5, 0, true, true); - crc_update2(&crc, 1, 1); /* CMD_READ */ - crc_update2(&crc, buff[0], 8); - crc_update2(&crc, buff[1], 8); - return reflect(crc_finish(&crc), 4); -} -// width=8 poly=0x63, reversed poly=0x8D init=0x55 refin=true refout=true xorout=0x0000 check=0xC6 name="CRC-8/LEGIC" -// the CRC needs to be reversed before returned. -uint32_t CRC8Legic(uint8_t *buff, size_t size) { - crc_t crc; - crc_init_ref(&crc, 8, 0x63, 0x55, 0, true, true); - for (size_t i = 0; i < size; ++i) { - crc_update2(&crc, buff[i], 8); - } - return reflect8(crc_finish(&crc)); -} -// width=8 poly=0x7, init=0x2C refin=false refout=false xorout=0x0000 check=0 name="CRC-8/CARDX" -uint32_t CRC8Cardx(uint8_t *buff, size_t size) { - crc_t crc; - crc_init_ref(&crc, 8, 0x7, 0x2C, 0, false, false); - for (size_t i = 0; i < size; ++i) { - crc_update2(&crc, buff[i], 8); - } - return crc_finish(&crc); -} - -uint32_t CRC8Hitag1(uint8_t *buff, size_t size) { - crc_t crc; - crc_init_ref(&crc, 8, 0x1d, 0xff, 0, false, false); - for (size_t i = 0; i < size; i++) { - crc_update2(&crc, buff[i], 8); - } - return crc_finish(&crc); -} - -uint32_t CRC8Hitag1Bits(const uint8_t *buff, size_t bitsize) { - crc_t crc; - uint8_t data = 0; - uint8_t n = 0; - crc_init_ref(&crc, 8, 0x1d, 0xff, 0, false, false); - size_t i; - for (i = 0; i < bitsize; i++) { - data <<= 1; - data += (buff[i / 8] >> (7 - (i % 8))) & 1; - n += 1; - if (n == 8) { - crc_update2(&crc, data, n); - n = 0; - data = 0; - } - } - if (n > 0) { - crc_update2(&crc, data, n); - } - return crc_finish(&crc); -} diff --git a/HardNestedSolver/pm3/crc.h b/HardNestedSolver/pm3/crc.h deleted file mode 100755 index 1715ef1..0000000 --- a/HardNestedSolver/pm3/crc.h +++ /dev/null @@ -1,93 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// See LICENSE.txt for the text of the license. -//----------------------------------------------------------------------------- -// Generic CRC calculation code. -//----------------------------------------------------------------------------- - -#ifndef __CRC_H -#define __CRC_H - -#include "common.h" - -typedef struct crc_ctx { - uint32_t state; - int order; - uint32_t polynom; - uint32_t initial_value; - uint32_t final_xor; - uint32_t mask; - int topbit; - bool refin; /* Parameter: Reflect input bytes? */ - bool refout; /* Parameter: Reflect output CRC? */ -} crc_t; - -/* Static initialization of a crc structure */ -#define CRC_INITIALIZER(_order, _polynom, _initial_value, _final_xor) { \ - .state = ((_initial_value) & ((1L<<(_order))-1)), \ - .order = (_order), \ - .polynom = (_polynom), \ - .initial_value = (_initial_value), \ - .final_xor = (_final_xor), \ - .mask = ((1L<<(_order))-1) \ - .refin = false, \ - .refout = false \ -} - -/* Initialize a crc structure. order is the order of the polynom, e.g. 32 for a CRC-32 - * polynom is the CRC polynom. initial_value is the initial value of a clean state. - * final_xor is XORed onto the state before returning it from crc_result(). - * refin is the setting for reversing (bitwise) the bytes during crc - * refot is the setting for reversing (bitwise) the crc byte before returning it. - */ -void crc_init_ref(crc_t *crc, int order, uint32_t polynom, uint32_t initial_value, uint32_t final_xor, bool refin, bool refout); - -/* Initialize a crc structure. order is the order of the polynom, e.g. 32 for a CRC-32 - * polynom is the CRC polynom. initial_value is the initial value of a clean state. - * final_xor is XORed onto the state before returning it from crc_result(). */ -void crc_init(crc_t *crc, int order, uint32_t polynom, uint32_t initial_value, uint32_t final_xor); - - -/* Update the crc state. data is the data of length data_width bits (only the - * data_width lower-most bits are used). - */ -void crc_update(crc_t *crc, uint32_t data, int data_width); -void crc_update2(crc_t *crc, uint32_t data, int data_width); - -/* Clean the crc state, e.g. reset it to initial_value */ -void crc_clear(crc_t *crc); - -/* Get the result of the crc calculation */ -uint32_t crc_finish(crc_t *crc); - -// Calculate CRC-8/Maxim checksum -uint32_t CRC8Maxim(uint8_t *buff, size_t size); - -// Calculate CRC-8 Mifare MAD checksum -uint32_t CRC8Mad(uint8_t *buff, size_t size); - -// Calculate CRC-4/Legic checksum -uint32_t CRC4Legic(uint8_t *buff, size_t size); - -// Calculate CRC-8/Legic checksum -uint32_t CRC8Legic(uint8_t *buff, size_t size); - -// Calculate CRC-8/Cardx checksum -uint32_t CRC8Cardx(uint8_t *buff, size_t size); - -// Calculate CRC-8/Hitag1, ZX8211 checksum -uint32_t CRC8Hitag1(uint8_t *buff, size_t size); -uint32_t CRC8Hitag1Bits(const uint8_t *buff, size_t bitsize); - -#endif /* __CRC_H */ diff --git a/HardNestedSolver/pm3/crc16.c b/HardNestedSolver/pm3/crc16.c deleted file mode 100755 index f78fab5..0000000 --- a/HardNestedSolver/pm3/crc16.c +++ /dev/null @@ -1,352 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// See LICENSE.txt for the text of the license. -//----------------------------------------------------------------------------- -// CRC16 -//----------------------------------------------------------------------------- -#include "crc16.h" - -#include -#include "commonutil.h" - -static uint16_t crc_table[256]; -static bool crc_table_init = false; -static CrcType_t current_crc_type = CRC_NONE; - -void init_table(CrcType_t crctype) { - - // same crc algo, and initialised already - if (crctype == current_crc_type && crc_table_init) - return; - - // not the same crc algo. reset table. - if (crctype != current_crc_type) - reset_table(); - - current_crc_type = crctype; - - switch (crctype) { - case CRC_14443_A: - case CRC_14443_B: - case CRC_15693: - case CRC_ICLASS: - case CRC_CRYPTORF: - generate_table(CRC16_POLY_CCITT, true); - break; - case CRC_FELICA: - case CRC_XMODEM: - generate_table(CRC16_POLY_CCITT, false); - break; - case CRC_LEGIC: - generate_table(CRC16_POLY_LEGIC, true); - break; - case CRC_LEGIC_16: - generate_table(CRC16_POLY_LEGIC_16, true); - break; - case CRC_CCITT: - generate_table(CRC16_POLY_CCITT, false); - break; - case CRC_KERMIT: - generate_table(CRC16_POLY_CCITT, true); - break; - case CRC_11784: - generate_table(CRC16_POLY_CCITT, false); - break; - case CRC_NONE: - crc_table_init = false; - current_crc_type = CRC_NONE; - break; - } -} - -void generate_table(uint16_t polynomial, bool refin) { - - for (uint16_t i = 0; i < 256; i++) { - uint16_t c, crc = 0; - if (refin) - c = reflect8(i) << 8; - else - c = i << 8; - - for (uint16_t j = 0; j < 8; j++) { - - if ((crc ^ c) & 0x8000) - crc = (crc << 1) ^ polynomial; - else - crc = crc << 1; - - c = c << 1; - } - if (refin) - crc = reflect16(crc); - - crc_table[i] = crc; - } - crc_table_init = true; -} - -void reset_table(void) { - memset(crc_table, 0, sizeof(crc_table)); - crc_table_init = false; - current_crc_type = CRC_NONE; -} - -// table lookup LUT solution -uint16_t crc16_fast(uint8_t const *d, size_t n, uint16_t initval, bool refin, bool refout) { - - // fast lookup table algorithm without augmented zero bytes, e.g. used in pkzip. - // only usable with polynom orders of 8, 16, 24 or 32. - if (n == 0) - return (~initval); - - uint16_t crc = initval; - - if (refin) - crc = reflect16(crc); - - if (!refin) - while (n--) crc = (crc << 8) ^ crc_table[((crc >> 8) ^ *d++) & 0xFF ]; - else - while (n--) crc = (crc >> 8) ^ crc_table[(crc & 0xFF) ^ *d++]; - - if (refout ^ refin) - crc = reflect16(crc); - - return crc; -} - -// bit looped solution TODO REMOVED -uint16_t update_crc16_ex(uint16_t crc, uint8_t c, uint16_t polynomial) { - uint16_t tmp = 0; - uint16_t v = (crc ^ c) & 0xff; - - for (uint16_t i = 0; i < 8; i++) { - - if ((tmp ^ v) & 1) - tmp = (tmp >> 1) ^ polynomial; - else - tmp >>= 1; - - v >>= 1; - } - return ((crc >> 8) ^ tmp) & 0xffff; -} -uint16_t update_crc16(uint16_t crc, uint8_t c) { - return update_crc16_ex(crc, c, CRC16_POLY_CCITT); -} - -// two ways. msb or lsb loop. -uint16_t Crc16(uint8_t const *d, size_t length, uint16_t remainder, uint16_t polynomial, bool refin, bool refout) { - if (length == 0) - return (~remainder); - - for (uint32_t i = 0; i < length; ++i) { - uint8_t c = d[i]; - if (refin) c = reflect8(c); - - // xor in at msb - remainder ^= (c << 8); - - // 8 iteration loop - for (uint8_t j = 8; j; --j) { - if (remainder & 0x8000) { - remainder = (remainder << 1) ^ polynomial; - } else { - remainder <<= 1; - } - } - } - if (refout) - remainder = reflect16(remainder); - - return remainder; -} - -void compute_crc(CrcType_t ct, const uint8_t *d, size_t n, uint8_t *first, uint8_t *second) { - - // can't calc a crc on less than 1 byte - if (n == 0) return; - - init_table(ct); - - uint16_t crc = 0; - switch (ct) { - case CRC_14443_A: - crc = crc16_a(d, n); - break; - case CRC_CRYPTORF: - case CRC_14443_B: - case CRC_15693: - crc = crc16_x25(d, n); - break; - case CRC_ICLASS: - crc = crc16_iclass(d, n); - break; - case CRC_FELICA: - case CRC_XMODEM: - crc = crc16_xmodem(d, n); - break; - case CRC_CCITT: - crc = crc16_ccitt(d, n); - break; - case CRC_KERMIT: - crc = crc16_kermit(d, n); - break; - case CRC_11784: - crc = crc16_fdxb(d, n); - break; - case CRC_LEGIC: - case CRC_LEGIC_16: - // TODO - return; - case CRC_NONE: - return; - } - *first = (crc & 0xFF); - *second = ((crc >> 8) & 0xFF); -} -uint16_t Crc16ex(CrcType_t ct, const uint8_t *d, size_t n) { - - // can't calc a crc on less than 3 byte. (1byte + 2 crc bytes) - if (n < 3) return 0; - - init_table(ct); - switch (ct) { - case CRC_14443_A: - return crc16_a(d, n); - case CRC_CRYPTORF: - case CRC_14443_B: - case CRC_15693: - return crc16_x25(d, n); - case CRC_ICLASS: - return crc16_iclass(d, n); - case CRC_FELICA: - case CRC_XMODEM: - return crc16_xmodem(d, n); - case CRC_CCITT: - return crc16_ccitt(d, n); - case CRC_KERMIT: - return crc16_kermit(d, n); - case CRC_11784: - return crc16_fdxb(d, n); - case CRC_LEGIC: - case CRC_LEGIC_16: - // TODO - return 0; - case CRC_NONE: - default: - break; - } - return 0; -} - -// check CRC -// ct crc type -// d buffer with data -// n length (including crc) -// -// This function uses the message + crc bytes in order to compare the "residue" afterwards. -// crc16 algos like CRC-A become 0x0000 -// while CRC-15693 become 0x0F47 -// If calculated with crc bytes, the residue should be 0xF0B8 -bool check_crc(CrcType_t ct, const uint8_t *d, size_t n) { - - // can't calc a crc on less than 3 byte. (1byte + 2 crc bytes) - if (n < 3) return false; - - init_table(ct); - - switch (ct) { - case CRC_14443_A: - return (crc16_a(d, n) == 0); - case CRC_CRYPTORF: - case CRC_14443_B: - return (crc16_x25(d, n) == X25_CRC_CHECK); - case CRC_15693: - return (crc16_x25(d, n) == X25_CRC_CHECK); - case CRC_ICLASS: - return (crc16_iclass(d, n) == 0); - case CRC_FELICA: - case CRC_XMODEM: - return (crc16_xmodem(d, n) == 0); - case CRC_CCITT: - return (crc16_ccitt(d, n) == 0); - case CRC_KERMIT: - return (crc16_kermit(d, n) == 0); - case CRC_11784: - return (crc16_fdxb(d, n) == 0); - case CRC_LEGIC: - case CRC_LEGIC_16: - // TODO - return false; - case CRC_NONE: - default: - break; - } - return false; -} - -// poly=0x1021 init=0xffff refin=false refout=false xorout=0x0000 check=0x29b1 residue=0x0000 name="CRC-16/CCITT-FALSE" -uint16_t crc16_ccitt(uint8_t const *d, size_t n) { - return crc16_fast(d, n, 0xffff, false, false); -} - -// FDX-B ISO11784/85) uses KERMIT/CCITT -// poly 0x xx init=0x000 refin=false refout=true xorout=0x0000 ... -uint16_t crc16_fdxb(uint8_t const *d, size_t n) { - return crc16_fast(d, n, 0x0000, false, true); -} - -// poly=0x1021 init=0x0000 refin=true refout=true xorout=0x0000 name="KERMIT" -uint16_t crc16_kermit(uint8_t const *d, size_t n) { - return crc16_fast(d, n, 0x0000, true, true); -} - -// FeliCa uses XMODEM -// poly=0x1021 init=0x0000 refin=false refout=false xorout=0x0000 name="XMODEM" -uint16_t crc16_xmodem(uint8_t const *d, size_t n) { - return crc16_fast(d, n, 0x0000, false, false); -} - -// Following standards uses X-25 -// ISO 15693, -// ISO 14443 CRC-B -// ISO/IEC 13239 (formerly ISO/IEC 3309) -// poly=0x1021 init=0xffff refin=true refout=true xorout=0xffff name="X-25" -uint16_t crc16_x25(uint8_t const *d, size_t n) { - uint16_t crc = crc16_fast(d, n, 0xffff, true, true); - crc = ~crc; - return crc; -} -// CRC-A (14443-3) -// poly=0x1021 init=0xc6c6 refin=true refout=true xorout=0x0000 name="CRC-A" -uint16_t crc16_a(uint8_t const *d, size_t n) { - return crc16_fast(d, n, 0xC6C6, true, true); -} - -// iClass crc -// initvalue 0x4807 reflected 0xE012 -// poly 0x1021 reflected 0x8408 -// poly=0x1021 init=0x4807 refin=true refout=true xorout=0x0BC3 check=0xF0B8 name="CRC-16/ICLASS" -uint16_t crc16_iclass(uint8_t const *d, size_t n) { - return crc16_fast(d, n, 0x4807, true, true); -} - -// This CRC-16 is used in Legic Advant systems. -// poly=0xB400, init=depends refin=true refout=true xorout=0x0000 check= name="CRC-16/LEGIC" -uint16_t crc16_legic(uint8_t const *d, size_t n, uint8_t uidcrc) { - uint16_t initial = (uidcrc << 8 | uidcrc); - return crc16_fast(d, n, initial, true, false); -} - diff --git a/HardNestedSolver/pm3/crc16.h b/HardNestedSolver/pm3/crc16.h deleted file mode 100755 index d9631c4..0000000 --- a/HardNestedSolver/pm3/crc16.h +++ /dev/null @@ -1,87 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// See LICENSE.txt for the text of the license. -//----------------------------------------------------------------------------- -// CRC16 -//----------------------------------------------------------------------------- -#ifndef __CRC16_H -#define __CRC16_H - -#include "common.h" - -#define CRC16_POLY_CCITT 0x1021 -#define CRC16_POLY_KERMIT 0x8408 -#define CRC16_POLY_LEGIC 0xc6c6 //0x6363 -#define CRC16_POLY_LEGIC_16 0x002d -#define CRC16_POLY_DNP 0x3d65 - -#define X25_CRC_CHECK ((uint16_t)(~0xF0B8 & 0xFFFF)) // use this for checking of a correct crc - -typedef enum { - CRC_NONE, - CRC_11784, - CRC_14443_A, - CRC_14443_B, - CRC_15693, - CRC_ICLASS, - CRC_FELICA, - CRC_LEGIC, - CRC_LEGIC_16, - CRC_CCITT, - CRC_KERMIT, - CRC_XMODEM, - CRC_CRYPTORF, -} CrcType_t; - -uint16_t update_crc16_ex(uint16_t crc, uint8_t c, uint16_t polynomial); -uint16_t update_crc16(uint16_t crc, uint8_t c); -uint16_t Crc16(uint8_t const *d, size_t length, uint16_t remainder, uint16_t polynomial, bool refin, bool refout); - -uint16_t Crc16ex(CrcType_t ct, const uint8_t *d, size_t n); -void compute_crc(CrcType_t ct, const uint8_t *d, size_t n, uint8_t *first, uint8_t *second); -bool check_crc(CrcType_t ct, const uint8_t *d, size_t n); - -// Calculate CRC-16/CCITT-FALSE -uint16_t crc16_ccitt(uint8_t const *d, size_t n); - -// Calculate CRC-16/KERMIT (FDX-B ISO11784/85) LF -uint16_t crc16_fdxb(uint8_t const *d, size_t n); - -// Calculate CRC-16/KERMIT -uint16_t crc16_kermit(uint8_t const *d, size_t n); - -// Calculate CRC-16/XMODEM (FeliCa) -uint16_t crc16_xmodem(uint8_t const *d, size_t n); - -// Calculate CRC-16/X25 (ISO15693, ISO14443 CRC-B,ISO/IEC 13239) -uint16_t crc16_x25(uint8_t const *d, size_t n); - -// Calculate CRC-16/CRC-A (ISO14443 CRC-A) -uint16_t crc16_a(uint8_t const *d, size_t n); - -// Calculate CRC-16/iCLASS -uint16_t crc16_iclass(uint8_t const *d, size_t n); - -// Calculate CRC-16/Legic -// the initial_value is based on the previous legic_Crc8 of the UID. -// ie: uidcrc = 0x78 then initial_value == 0x7878 -uint16_t crc16_legic(uint8_t const *d, size_t n, uint8_t uidcrc); - -// table implementation -void init_table(CrcType_t crctype); -void reset_table(void); -void generate_table(uint16_t polynomial, bool refin); -uint16_t crc16_fast(uint8_t const *d, size_t n, uint16_t initval, bool refin, bool refout); - -#endif diff --git a/HardNestedSolver/pm3/crc32.c b/HardNestedSolver/pm3/crc32.c deleted file mode 100755 index 17b1264..0000000 --- a/HardNestedSolver/pm3/crc32.c +++ /dev/null @@ -1,50 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// See LICENSE.txt for the text of the license. -//----------------------------------------------------------------------------- -#include "crc32.h" - -#define htole32(x) (x) -#define CRC32_PRESET 0xFFFFFFFF - -static void crc32_byte(uint32_t *crc, const uint8_t value); - -static void crc32_byte(uint32_t *crc, const uint8_t value) { - /* x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1 */ - const uint32_t poly = 0xEDB88320; - - *crc ^= value; - for (int current_bit = 7; current_bit >= 0; current_bit--) { - int bit_out = (*crc) & 0x00000001; - *crc >>= 1; - if (bit_out) - *crc ^= poly; - } -} - -void crc32_ex(const uint8_t *d, const size_t n, uint8_t *crc) { - uint32_t c = CRC32_PRESET; - for (size_t i = 0; i < n; i++) { - crc32_byte(&c, d[i]); - } - crc[0] = (uint8_t) c; - crc[1] = (uint8_t)(c >> 8); - crc[2] = (uint8_t)(c >> 16); - crc[3] = (uint8_t)(c >> 24); -} - - -void crc32_append(uint8_t *d, const size_t n) { - crc32_ex(d, n, d + n); -} diff --git a/HardNestedSolver/pm3/crc32.h b/HardNestedSolver/pm3/crc32.h deleted file mode 100755 index 405f19b..0000000 --- a/HardNestedSolver/pm3/crc32.h +++ /dev/null @@ -1,27 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// See LICENSE.txt for the text of the license. -//----------------------------------------------------------------------------- -// CRC32 -//----------------------------------------------------------------------------- - -#ifndef __CRC32_H -#define __CRC32_H - -#include "common.h" - -void crc32_ex(const uint8_t *d, const size_t n, uint8_t *crc); -void crc32_append(uint8_t *d, const size_t n); - -#endif diff --git a/HardNestedSolver/pm3/crc64.c b/HardNestedSolver/pm3/crc64.c deleted file mode 100755 index 842a1a4..0000000 --- a/HardNestedSolver/pm3/crc64.c +++ /dev/null @@ -1,96 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// See LICENSE.txt for the text of the license. -//----------------------------------------------------------------------------- -#include "crc64.h" - -#define CRC64_ISO_PRESET 0xFFFFFFFFFFFFFFFF -#define CRC64_ECMA_PRESET 0x0000000000000000 - -static const uint64_t crc64_table[] = { - 0x0000000000000000, 0x42F0E1EBA9EA3693, 0x85E1C3D753D46D26, 0xC711223CFA3E5BB5, - 0x493366450E42ECDF, 0x0BC387AEA7A8DA4C, 0xCCD2A5925D9681F9, 0x8E224479F47CB76A, - 0x9266CC8A1C85D9BE, 0xD0962D61B56FEF2D, 0x17870F5D4F51B498, 0x5577EEB6E6BB820B, - 0xDB55AACF12C73561, 0x99A54B24BB2D03F2, 0x5EB4691841135847, 0x1C4488F3E8F96ED4, - 0x663D78FF90E185EF, 0x24CD9914390BB37C, 0xE3DCBB28C335E8C9, 0xA12C5AC36ADFDE5A, - 0x2F0E1EBA9EA36930, 0x6DFEFF5137495FA3, 0xAAEFDD6DCD770416, 0xE81F3C86649D3285, - 0xF45BB4758C645C51, 0xB6AB559E258E6AC2, 0x71BA77A2DFB03177, 0x334A9649765A07E4, - 0xBD68D2308226B08E, 0xFF9833DB2BCC861D, 0x388911E7D1F2DDA8, 0x7A79F00C7818EB3B, - 0xCC7AF1FF21C30BDE, 0x8E8A101488293D4D, 0x499B3228721766F8, 0x0B6BD3C3DBFD506B, - 0x854997BA2F81E701, 0xC7B97651866BD192, 0x00A8546D7C558A27, 0x4258B586D5BFBCB4, - 0x5E1C3D753D46D260, 0x1CECDC9E94ACE4F3, 0xDBFDFEA26E92BF46, 0x990D1F49C77889D5, - 0x172F5B3033043EBF, 0x55DFBADB9AEE082C, 0x92CE98E760D05399, 0xD03E790CC93A650A, - 0xAA478900B1228E31, 0xE8B768EB18C8B8A2, 0x2FA64AD7E2F6E317, 0x6D56AB3C4B1CD584, - 0xE374EF45BF6062EE, 0xA1840EAE168A547D, 0x66952C92ECB40FC8, 0x2465CD79455E395B, - 0x3821458AADA7578F, 0x7AD1A461044D611C, 0xBDC0865DFE733AA9, 0xFF3067B657990C3A, - 0x711223CFA3E5BB50, 0x33E2C2240A0F8DC3, 0xF4F3E018F031D676, 0xB60301F359DBE0E5, - 0xDA050215EA6C212F, 0x98F5E3FE438617BC, 0x5FE4C1C2B9B84C09, 0x1D14202910527A9A, - 0x93366450E42ECDF0, 0xD1C685BB4DC4FB63, 0x16D7A787B7FAA0D6, 0x5427466C1E109645, - 0x4863CE9FF6E9F891, 0x0A932F745F03CE02, 0xCD820D48A53D95B7, 0x8F72ECA30CD7A324, - 0x0150A8DAF8AB144E, 0x43A04931514122DD, 0x84B16B0DAB7F7968, 0xC6418AE602954FFB, - 0xBC387AEA7A8DA4C0, 0xFEC89B01D3679253, 0x39D9B93D2959C9E6, 0x7B2958D680B3FF75, - 0xF50B1CAF74CF481F, 0xB7FBFD44DD257E8C, 0x70EADF78271B2539, 0x321A3E938EF113AA, - 0x2E5EB66066087D7E, 0x6CAE578BCFE24BED, 0xABBF75B735DC1058, 0xE94F945C9C3626CB, - 0x676DD025684A91A1, 0x259D31CEC1A0A732, 0xE28C13F23B9EFC87, 0xA07CF2199274CA14, - 0x167FF3EACBAF2AF1, 0x548F120162451C62, 0x939E303D987B47D7, 0xD16ED1D631917144, - 0x5F4C95AFC5EDC62E, 0x1DBC74446C07F0BD, 0xDAAD56789639AB08, 0x985DB7933FD39D9B, - 0x84193F60D72AF34F, 0xC6E9DE8B7EC0C5DC, 0x01F8FCB784FE9E69, 0x43081D5C2D14A8FA, - 0xCD2A5925D9681F90, 0x8FDAB8CE70822903, 0x48CB9AF28ABC72B6, 0x0A3B7B1923564425, - 0x70428B155B4EAF1E, 0x32B26AFEF2A4998D, 0xF5A348C2089AC238, 0xB753A929A170F4AB, - 0x3971ED50550C43C1, 0x7B810CBBFCE67552, 0xBC902E8706D82EE7, 0xFE60CF6CAF321874, - 0xE224479F47CB76A0, 0xA0D4A674EE214033, 0x67C58448141F1B86, 0x253565A3BDF52D15, - 0xAB1721DA49899A7F, 0xE9E7C031E063ACEC, 0x2EF6E20D1A5DF759, 0x6C0603E6B3B7C1CA, - 0xF6FAE5C07D3274CD, 0xB40A042BD4D8425E, 0x731B26172EE619EB, 0x31EBC7FC870C2F78, - 0xBFC9838573709812, 0xFD39626EDA9AAE81, 0x3A28405220A4F534, 0x78D8A1B9894EC3A7, - 0x649C294A61B7AD73, 0x266CC8A1C85D9BE0, 0xE17DEA9D3263C055, 0xA38D0B769B89F6C6, - 0x2DAF4F0F6FF541AC, 0x6F5FAEE4C61F773F, 0xA84E8CD83C212C8A, 0xEABE6D3395CB1A19, - 0x90C79D3FEDD3F122, 0xD2377CD44439C7B1, 0x15265EE8BE079C04, 0x57D6BF0317EDAA97, - 0xD9F4FB7AE3911DFD, 0x9B041A914A7B2B6E, 0x5C1538ADB04570DB, 0x1EE5D94619AF4648, - 0x02A151B5F156289C, 0x4051B05E58BC1E0F, 0x87409262A28245BA, 0xC5B073890B687329, - 0x4B9237F0FF14C443, 0x0962D61B56FEF2D0, 0xCE73F427ACC0A965, 0x8C8315CC052A9FF6, - 0x3A80143F5CF17F13, 0x7870F5D4F51B4980, 0xBF61D7E80F251235, 0xFD913603A6CF24A6, - 0x73B3727A52B393CC, 0x31439391FB59A55F, 0xF652B1AD0167FEEA, 0xB4A25046A88DC879, - 0xA8E6D8B54074A6AD, 0xEA16395EE99E903E, 0x2D071B6213A0CB8B, 0x6FF7FA89BA4AFD18, - 0xE1D5BEF04E364A72, 0xA3255F1BE7DC7CE1, 0x64347D271DE22754, 0x26C49CCCB40811C7, - 0x5CBD6CC0CC10FAFC, 0x1E4D8D2B65FACC6F, 0xD95CAF179FC497DA, 0x9BAC4EFC362EA149, - 0x158E0A85C2521623, 0x577EEB6E6BB820B0, 0x906FC95291867B05, 0xD29F28B9386C4D96, - 0xCEDBA04AD0952342, 0x8C2B41A1797F15D1, 0x4B3A639D83414E64, 0x09CA82762AAB78F7, - 0x87E8C60FDED7CF9D, 0xC51827E4773DF90E, 0x020905D88D03A2BB, 0x40F9E43324E99428, - 0x2CFFE7D5975E55E2, 0x6E0F063E3EB46371, 0xA91E2402C48A38C4, 0xEBEEC5E96D600E57, - 0x65CC8190991CB93D, 0x273C607B30F68FAE, 0xE02D4247CAC8D41B, 0xA2DDA3AC6322E288, - 0xBE992B5F8BDB8C5C, 0xFC69CAB42231BACF, 0x3B78E888D80FE17A, 0x7988096371E5D7E9, - 0xF7AA4D1A85996083, 0xB55AACF12C735610, 0x724B8ECDD64D0DA5, 0x30BB6F267FA73B36, - 0x4AC29F2A07BFD00D, 0x08327EC1AE55E69E, 0xCF235CFD546BBD2B, 0x8DD3BD16FD818BB8, - 0x03F1F96F09FD3CD2, 0x41011884A0170A41, 0x86103AB85A2951F4, 0xC4E0DB53F3C36767, - 0xD8A453A01B3A09B3, 0x9A54B24BB2D03F20, 0x5D45907748EE6495, 0x1FB5719CE1045206, - 0x919735E51578E56C, 0xD367D40EBC92D3FF, 0x1476F63246AC884A, 0x568617D9EF46BED9, - 0xE085162AB69D5E3C, 0xA275F7C11F7768AF, 0x6564D5FDE549331A, 0x279434164CA30589, - 0xA9B6706FB8DFB2E3, 0xEB46918411358470, 0x2C57B3B8EB0BDFC5, 0x6EA7525342E1E956, - 0x72E3DAA0AA188782, 0x30133B4B03F2B111, 0xF7021977F9CCEAA4, 0xB5F2F89C5026DC37, - 0x3BD0BCE5A45A6B5D, 0x79205D0E0DB05DCE, 0xBE317F32F78E067B, 0xFCC19ED95E6430E8, - 0x86B86ED5267CDBD3, 0xC4488F3E8F96ED40, 0x0359AD0275A8B6F5, 0x41A94CE9DC428066, - 0xCF8B0890283E370C, 0x8D7BE97B81D4019F, 0x4A6ACB477BEA5A2A, 0x089A2AACD2006CB9, - 0x14DEA25F3AF9026D, 0x562E43B4931334FE, 0x913F6188692D6F4B, 0xD3CF8063C0C759D8, - 0x5DEDC41A34BBEEB2, 0x1F1D25F19D51D821, 0xD80C07CD676F8394, 0x9AFCE626CE85B507 -}; - -void crc64(const uint8_t *data, const size_t len, uint64_t *crc) { - - for (size_t i = 0; i < len; i++) { - uint8_t tableIndex = (((uint8_t)(*crc >> 56)) ^ data[i]) & 0xff; - *crc = crc64_table[tableIndex] ^ (*crc << 8); - } -} - -//suint8_t x = (c & 0xFF00000000000000 ) >> 56; diff --git a/HardNestedSolver/pm3/crc64.h b/HardNestedSolver/pm3/crc64.h deleted file mode 100755 index dbd2b84..0000000 --- a/HardNestedSolver/pm3/crc64.h +++ /dev/null @@ -1,26 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// See LICENSE.txt for the text of the license. -//----------------------------------------------------------------------------- -// CRC64 ECMA -//----------------------------------------------------------------------------- - -#ifndef __CRC64_H -#define __CRC64_H - -#include "common.h" - -void crc64(const uint8_t *data, const size_t len, uint64_t *crc) ; - -#endif diff --git a/HardNestedSolver/pm3/fileutils.c b/HardNestedSolver/pm3/fileutils.c deleted file mode 100755 index 4930536..0000000 --- a/HardNestedSolver/pm3/fileutils.c +++ /dev/null @@ -1,1414 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// See LICENSE.txt for the text of the license. -//----------------------------------------------------------------------------- - -// this define is needed for scandir/alphasort to work -#define _GNU_SOURCE -#include "fileutils.h" - -//#include -#include - -#include "pm3_cmd.h" -#include "commonutil.h" -#include "util.h" -//#include - -#ifdef _WIN32 -//#include "scandir.h" -#include -#include -#include -#include -#include -typedef int (*filter_func_t)(const struct dirent *); - -struct dirent { - char d_name[1024]; -}; - -int alphasort(const struct dirent **a, const struct dirent **b) { - return stricmp((*a)->d_name, (*b)->d_name); -} - -int scandir(const char *path, struct dirent ***namelist, filter_func_t filter, int (*compar)(const struct dirent **, const struct dirent **)) { - WIN32_FIND_DATA FindFileData; - HANDLE hFind; - char search_path[1024]; - int count = 0; - - strcpy(search_path, path); - strcat(search_path, "\\*"); - - hFind = FindFirstFile(search_path, &FindFileData); - - if (hFind == INVALID_HANDLE_VALUE) { - return -1; - } - - do { - if (filter != NULL && filter(&FindFileData) == 0) { - continue; - } - - count++; - } while (FindNextFile(hFind, &FindFileData) != 0); - - FindClose(hFind); - - *namelist = (struct dirent **)malloc(count * sizeof(struct dirent *)); - - if (*namelist == NULL) { - return -1; - } - - count = 0; - - hFind = FindFirstFile(search_path, &FindFileData); - - do { - if (filter != NULL && filter(&FindFileData) == 0) { - continue; - } - - struct dirent *entry = (struct dirent *)malloc(sizeof(struct dirent)); - - if (entry == NULL) { - return -1; - } - - strcpy(entry->d_name, FindFileData.cFileName); - - (*namelist)[count++] = entry; - } while (FindNextFile(hFind, &FindFileData) != 0); - - FindClose(hFind); - - if (compar != NULL) { - qsort(*namelist, count, sizeof(struct dirent *), compar); - } - - return count; -} -#include -#else -#include -#endif - -#ifdef __APPLE__ -#include /* for _NSGetExecutablePath */ -#elif defined(__linux__) -#include /* for PATH_MAX */ -#elif defined(_WIN32) -#include /* for GetModuleFileName */ -#endif - -char *getExecutablePath(char *buffer, size_t size) { - if (buffer == NULL) { - return NULL; - } - -#ifdef __APPLE__ - if (_NSGetExecutablePath(buffer, &size) == 0) { - return buffer; - } -#elif defined(__linux__) - ssize_t count = readlink("/proc/self/exe", buffer, size - 1); - if (count != -1) { - buffer[count] = '\0'; - return buffer; - } -#elif defined(_WIN32) - DWORD length = GetModuleFileName(NULL, buffer, size); - if (length > 0 && length < size) { - return buffer; - } -#endif - - return NULL; -} - -#define PATH_MAX_LENGTH 200 - - -#ifndef getcwd -#ifdef _MSC_VER -#include -#define getcwd(buffer, size) GetCurrentDirectoryA(size, buffer) -#else -#include -#endif -#endif - -#define GetCurrentDir getcwd -/** - * @brief detects if file is of a supported filetype based on extension - * @param filename - * @return o - */ -DumpFileType_t getfiletype(const char *filename) { - // assume unknown file is BINARY - DumpFileType_t o = BIN; - if (filename == NULL) { - return o; - } - - size_t len = strlen(filename); - if (len > 4) { - // check if valid file extension and attempt to load data - char s[FILE_PATH_SIZE]; - memset(s, 0, sizeof(s)); - memcpy(s, filename, len); - str_lower(s); - - if (str_endswith(s, "bin")) { - o = BIN; - } else if (str_endswith(s, "eml")) { - o = EML; - } else if (str_endswith(s, "json")) { - o = JSON; - } else if (str_endswith(s, "dic")) { - o = DICTIONARY; - } else { - // mfd, trc, trace is binary - o = BIN; - // log is text - // .pm3 is text values of signal data - } - } - return o; -} - -/** - * @brief checks if a file exists - * @param filename - * @return - */ -int fileExists(const char *filename) { - -#ifdef _WIN32 - struct _stat st; - int result = _stat(filename, &st); -#else - struct stat st; - int result = stat(filename, &st); -#endif - return result == 0; -} - -/** - * @brief checks if path is directory. - * @param filename - * @return - */ -static bool is_directory(const char *filename) { -#ifdef _WIN32 - struct _stat st; - if (_stat(filename, &st) == -1) - return false; -#else - struct stat st; -// stat(filename, &st); - if (lstat(filename, &st) == -1) - return false; -#endif -} - -bool setDefaultPath(savePaths_t pathIndex, const char *path) { - - if (pathIndex < spItemCount) { - - if ((path == NULL) && (g_session.defaultPaths[pathIndex] != NULL)) { - free(g_session.defaultPaths[pathIndex]); - g_session.defaultPaths[pathIndex] = NULL; - } - - if (path == NULL) { - return false; - } - - size_t len = strlen(path); - - g_session.defaultPaths[pathIndex] = (char *)realloc(g_session.defaultPaths[pathIndex], len + 1); - strcpy(g_session.defaultPaths[pathIndex], path); - return true; - } - return false; -} - -static char *filenamemcopy(const char *preferredName, const char *suffix) { - if (preferredName == NULL) return NULL; - if (suffix == NULL) return NULL; - - char *fileName = (char *) calloc(strlen(preferredName) + strlen(suffix) + 1, sizeof(uint8_t)); - if (fileName == NULL) { - return NULL; - } - - strcpy(fileName, preferredName); - if (str_endswith(fileName, suffix)) { - return fileName; - } - - strcat(fileName, suffix); - return fileName; -} - -static size_t path_size(savePaths_t a) { - if (a == spItemCount) { - return 0; - } - return strlen(g_session.defaultPaths[a]); -} - -char *newfilenamemcopyEx(const char *preferredName, const char *suffix, savePaths_t e_save_path) { - if (preferredName == NULL || suffix == NULL) { - return NULL; - } - - uint16_t p_namelen = strlen(preferredName); - if (str_endswith(preferredName, suffix)) { - p_namelen -= strlen(suffix); - } - - int save_path_len = path_size(e_save_path); - - // 1: null terminator - // 16: room for filenum to ensure new filename - // save_path_len + strlen(PATHSEP): the user preference save paths - const size_t len = p_namelen + strlen(suffix) + 1 + 16 + save_path_len + strlen(PATHSEP); - - char *fileName = (char *) calloc(len, sizeof(uint8_t)); - if (fileName == NULL) { - return NULL; - } - - char *pfn = fileName; - - // user preference save paths - if (save_path_len) { - snprintf(pfn, save_path_len + strlen(PATHSEP) + 1, "%s%s", g_session.defaultPaths[e_save_path], PATHSEP); - pfn += save_path_len + strlen(PATHSEP); - } - - int num = 1; - - // modify filename - snprintf(pfn, len, "%.*s%s", p_namelen, preferredName, suffix); - - // check complete path/filename if exists - while (fileExists(fileName)) { - // modify filename - snprintf(pfn, len, "%.*s-%03d%s", p_namelen, preferredName, num, suffix); - num++; - } - - return fileName; -} - -char *newfilenamemcopy(const char *preferredName, const char *suffix) { - return newfilenamemcopyEx(preferredName, suffix, spDefault); -} - -// --------- SAVE FILES -int saveFile(const char *preferredName, const char *suffix, const void *data, size_t datalen) { - - if (data == NULL || datalen == 0) { - return PM3_EINVARG; - } - - char *fileName = newfilenamemcopy(preferredName, suffix); - if (fileName == NULL) { - return PM3_EMALLOC; - } - - // We should have a valid filename now, e.g. dumpdata-3.bin - - // Opening file for writing in binary mode - FILE *f = fopen(fileName, "wb"); - if (!f) { - PrintAndLogEx(WARNING, "file not found or locked `" _YELLOW_("%s") "`", fileName); - free(fileName); - return PM3_EFILE; - } - fwrite(data, 1, datalen, f); - fflush(f); - fclose(f); - PrintAndLogEx(SUCCESS, "saved " _YELLOW_("%zu") " bytes to binary file " _YELLOW_("%s"), datalen, fileName); - free(fileName); - return PM3_SUCCESS; -} - -// dump file -int saveFileEML(const char *preferredName, uint8_t *data, size_t datalen, size_t blocksize) { - - if (data == NULL || datalen == 0) { - return PM3_EINVARG; - } - - char *fileName = newfilenamemcopyEx(preferredName, ".eml", spDump); - if (fileName == NULL) { - return PM3_EMALLOC; - } - - int retval = PM3_SUCCESS; - int blocks = datalen / blocksize; - uint16_t currblock = 1; - - // We should have a valid filename now, e.g. dumpdata-3.bin - - // Opening file for writing in text mode - FILE *f = fopen(fileName, "w+"); - if (!f) { - PrintAndLogEx(WARNING, "file not found or locked `" _YELLOW_("%s") "`", fileName); - retval = PM3_EFILE; - goto out; - } - - for (size_t i = 0; i < datalen; i++) { - fprintf(f, "%02X", data[i]); - - // no extra line in the end - if ((i + 1) % blocksize == 0 && currblock != blocks) { - fprintf(f, "\n"); - currblock++; - } - } - // left overs - if (datalen % blocksize != 0) { - int index = blocks * blocksize; - for (size_t j = 0; j < datalen % blocksize; j++) { - fprintf(f, "%02X", data[index + j]); - } - } - fflush(f); - fclose(f); - PrintAndLogEx(SUCCESS, "saved " _YELLOW_("%" PRId32) " blocks to text file " _YELLOW_("%s"), blocks, fileName); - - out: - free(fileName); - return retval; -} - -// wave file of trace, - -// Signal trace file, PM3 -int saveFilePM3(const char *preferredName, int *data, size_t datalen) { - - if (data == NULL || datalen == 0) { - return PM3_EINVARG; - } - - char *fileName = newfilenamemcopyEx(preferredName, ".pm3", spTrace); - if (fileName == NULL) { - return PM3_EMALLOC; - } - - int retval = PM3_SUCCESS; - - FILE *f = fopen(fileName, "w"); - if (!f) { - PrintAndLogEx(WARNING, "file not found or locked `" _YELLOW_("%s") "`", fileName); - retval = PM3_EFILE; - goto out; - } - - for (uint32_t i = 0; i < datalen; i++) { - fprintf(f, "%d\n", data[i]); - } - - fflush(f); - fclose(f); - PrintAndLogEx(SUCCESS, "saved " _YELLOW_("%zu") " bytes to PM3 file " _YELLOW_("'%s'"), datalen, fileName); - - out: - free(fileName); - return retval; -} - -// key file dump -int createMfcKeyDump(const char *preferredName, uint8_t sectorsCnt, sector_t *e_sector) { - - if (e_sector == NULL) return PM3_EINVARG; - - char *fileName = newfilenamemcopyEx(preferredName, ".bin", spDump); - if (fileName == NULL) return PM3_EMALLOC; - - FILE *f = fopen(fileName, "wb"); - if (f == NULL) { - PrintAndLogEx(WARNING, "Could not create file " _YELLOW_("%s"), fileName); - free(fileName); - return PM3_EFILE; - } - PrintAndLogEx(SUCCESS, "Generating binary key file"); - - uint8_t empty[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; - uint8_t tmp[6] = {0, 0, 0, 0, 0, 0}; - - for (int i = 0; i < sectorsCnt; i++) { - if (e_sector[i].foundKey[0]) - num_to_bytes(e_sector[i].Key[0], sizeof(tmp), tmp); - else - memcpy(tmp, empty, sizeof(tmp)); - fwrite(tmp, 1, sizeof(tmp), f); - } - - for (int i = 0; i < sectorsCnt; i++) { - if (e_sector[i].foundKey[0]) - num_to_bytes(e_sector[i].Key[1], sizeof(tmp), tmp); - else - memcpy(tmp, empty, sizeof(tmp)); - fwrite(tmp, 1, sizeof(tmp), f); - } - - fflush(f); - fclose(f); - PrintAndLogEx(SUCCESS, "Found keys have been dumped to " _YELLOW_("%s"), fileName); - PrintAndLogEx(INFO, "FYI! --> " _YELLOW_("0xFFFFFFFFFFFF") " <-- has been inserted for unknown keys where " _YELLOW_("res") " is " _YELLOW_("0")); - free(fileName); - return PM3_SUCCESS; -} - -// --------- LOAD FILES -int loadFile_safe(const char *preferredName, const char *suffix, void **pdata, size_t *datalen) { - return loadFile_safeEx(preferredName, suffix, pdata, datalen, true); -} -int loadFile_safeEx(const char *preferredName, const char *suffix, void **pdata, size_t *datalen, bool verbose) { - - char *path; - int res = searchFile(&path, RESOURCES_SUBDIR, preferredName, suffix, false); - if (res != PM3_SUCCESS) { - return PM3_EFILE; - } - - FILE *f = fopen(path, "rb"); - if (!f) { - PrintAndLogEx(WARNING, "file not found or locked `" _YELLOW_("%s") "`", path); - free(path); - return PM3_EFILE; - } - free(path); - - // get filesize in order to malloc memory - fseek(f, 0, SEEK_END); - long fsize = ftell(f); - fseek(f, 0, SEEK_SET); - - if (fsize <= 0) { - PrintAndLogEx(FAILED, "error, when getting filesize"); - fclose(f); - return PM3_EFILE; - } - - *pdata = calloc(fsize, sizeof(uint8_t)); - if (!*pdata) { - PrintAndLogEx(FAILED, "error, cannot allocate memory"); - fclose(f); - return PM3_EMALLOC; - } - - size_t bytes_read = fread(*pdata, 1, fsize, f); - - fclose(f); - - if (bytes_read != fsize) { - PrintAndLogEx(FAILED, "error, bytes read mismatch file size"); - free(*pdata); - return PM3_EFILE; - } - - *datalen = bytes_read; - - if (verbose) { - PrintAndLogEx(SUCCESS, "loaded " _YELLOW_("%zu") " bytes from binary file " _YELLOW_("%s"), bytes_read, preferredName); - } - return PM3_SUCCESS; -} - -int loadFileEML_safe(const char *preferredName, void **pdata, size_t *datalen) { - char *path; - int res = searchFile(&path, RESOURCES_SUBDIR, preferredName, "", false); - if (res != PM3_SUCCESS) { - return PM3_EFILE; - } - - FILE *f = fopen(path, "r"); - if (!f) { - PrintAndLogEx(WARNING, "file not found or locked `" _YELLOW_("%s") "`", path); - free(path); - return PM3_EFILE; - } - free(path); - - // get filesize in order to malloc memory - fseek(f, 0, SEEK_END); - long fsize = ftell(f); - fseek(f, 0, SEEK_SET); - - if (fsize <= 0) { - PrintAndLogEx(FAILED, "error, when getting filesize"); - fclose(f); - return PM3_EFILE; - } - - *pdata = calloc(fsize, sizeof(uint8_t)); - if (!*pdata) { - PrintAndLogEx(FAILED, "error, cannot allocate memory"); - fclose(f); - return PM3_EMALLOC; - } - - // 128 + 2 newline chars + 1 null terminator - char line[131]; - memset(line, 0, sizeof(line)); - uint8_t buf[64] = {0x00}; - size_t counter = 0; - int retval = PM3_SUCCESS, hexlen = 0; - - uint8_t *tmp = (uint8_t *)*pdata; - - while (!feof(f)) { - - memset(line, 0, sizeof(line)); - - if (fgets(line, sizeof(line), f) == NULL) { - if (feof(f)) - break; - - fclose(f); - PrintAndLogEx(FAILED, "File reading error."); - return PM3_EFILE; - } - - if (line[0] == '#') - continue; - - strcleanrn(line, sizeof(line)); - - res = param_gethex_to_eol(line, 0, buf, sizeof(buf), &hexlen); - if (res == 0) { - memcpy(tmp + counter, buf, hexlen); - counter += hexlen; - } else { - retval = PM3_ESOFT; - } - } - fclose(f); - PrintAndLogEx(SUCCESS, "loaded " _YELLOW_("%zu") " bytes from text file " _YELLOW_("%s"), counter, preferredName); - - - uint8_t *newdump = realloc(*pdata, counter); - if (newdump == NULL) { - free(*pdata); - return PM3_EMALLOC; - } else { - *pdata = newdump; - } - - if (datalen) - *datalen = counter; - - return retval; -} - -int loadFileMCT_safe(const char *preferredName, void **pdata, size_t *datalen) { - char *path; - int res = searchFile(&path, RESOURCES_SUBDIR, preferredName, "", false); - if (res != PM3_SUCCESS) { - return PM3_EFILE; - } - - FILE *f = fopen(path, "r"); - if (!f) { - PrintAndLogEx(WARNING, "file not found or locked `" _YELLOW_("%s") "`", path); - free(path); - return PM3_EFILE; - } - free(path); - - // get filesize in order to malloc memory - fseek(f, 0, SEEK_END); - long fsize = ftell(f); - fseek(f, 0, SEEK_SET); - - if (fsize <= 0) { - PrintAndLogEx(FAILED, "error, when getting filesize"); - fclose(f); - return PM3_EFILE; - } - - *pdata = calloc(fsize, sizeof(uint8_t)); - if (!*pdata) { - PrintAndLogEx(FAILED, "error, cannot allocate memory"); - fclose(f); - return PM3_EMALLOC; - } - - // 128 + 2 newline chars + 1 null terminator - char line[131]; - memset(line, 0, sizeof(line)); - uint8_t buf[64] = {0x00}; - size_t counter = 0; - int retval = PM3_SUCCESS, hexlen = 0; - - uint8_t *tmp = (uint8_t *)*pdata; - - while (!feof(f)) { - - memset(line, 0, sizeof(line)); - - if (fgets(line, sizeof(line), f) == NULL) { - if (feof(f)) - break; - - fclose(f); - PrintAndLogEx(FAILED, "File reading error."); - return PM3_EFILE; - } - - // skip lines like "+Sector:" - if (line[0] == '+') - continue; - - strcleanrn(line, sizeof(line)); - - res = param_gethex_to_eol(line, 0, buf, sizeof(buf), &hexlen); - if (res == 0) { - memcpy(tmp + counter, buf, hexlen); - counter += hexlen; - } else { - retval = PM3_ESOFT; - } - } - fclose(f); - PrintAndLogEx(SUCCESS, "loaded " _YELLOW_("%zu") " bytes from MCT file " _YELLOW_("%s"), counter, preferredName); - - - uint8_t *newdump = realloc(*pdata, counter); - if (newdump == NULL) { - free(*pdata); - return PM3_EMALLOC; - } else { - *pdata = newdump; - } - - if (datalen) - *datalen = counter; - - return retval; -} - -// iceman: todo - move all unsafe functions like this from client source. -int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, uint8_t keylen, uint32_t *keycnt) { - // t5577 == 4 bytes - // mifare == 6 bytes - // mf plus == 16 bytes - // mf desfire == 3des3k 24 bytes - // iclass == 8 bytes - // default to 6 bytes. - if (keylen != 4 && keylen != 6 && keylen != 8 && keylen != 16 && keylen != 24) { - keylen = 6; - } - - return loadFileDICTIONARYEx(preferredName, data, 0, datalen, keylen, keycnt, 0, NULL, true); -} - -int loadFileDICTIONARYEx(const char *preferredName, void *data, size_t maxdatalen, size_t *datalen, uint8_t keylen, uint32_t *keycnt, - size_t startFilePosition, size_t *endFilePosition, bool verbose) { - - if (data == NULL) return PM3_EINVARG; - - if (endFilePosition) - *endFilePosition = 0; - - char *path; - if (searchFile(&path, DICTIONARIES_SUBDIR, preferredName, ".dic", false) != PM3_SUCCESS) - return PM3_EFILE; - - // double up since its chars - keylen <<= 1; - - char line[255]; - uint32_t vkeycnt = 0; - size_t counter = 0; - int retval = PM3_SUCCESS; - - FILE *f = fopen(path, "r"); - if (!f) { - PrintAndLogEx(WARNING, "file not found or locked `" _YELLOW_("%s") "`", path); - retval = PM3_EFILE; - goto out; - } - - if (startFilePosition) { - if (fseek(f, startFilePosition, SEEK_SET) < 0) { - fclose(f); - retval = PM3_EFILE; - goto out; - } - } - - uint8_t *udata = (uint8_t *)data; - - // read file - while (!feof(f)) { - long filepos = ftell(f); - - if (!fgets(line, sizeof(line), f)) { - if (endFilePosition) - *endFilePosition = 0; - break; - } - - // add null terminator - line[keylen] = 0; - - // smaller keys than expected is skipped - if (strlen(line) < keylen) - continue; - - // The line start with # is comment, skip - if (line[0] == '#') - continue; - - if (!CheckStringIsHEXValue(line)) - continue; - - // cant store more data - if (maxdatalen && (counter + (keylen >> 1) > maxdatalen)) { - retval = 1; - if (endFilePosition) - *endFilePosition = filepos; - break; - } - - if (hex_to_bytes(line, udata + counter, keylen >> 1) != (keylen >> 1)) - continue; - - vkeycnt++; - memset(line, 0, sizeof(line)); - counter += (keylen >> 1); - } - fclose(f); - if (verbose) - PrintAndLogEx(SUCCESS, "loaded " _GREEN_("%2d") " keys from dictionary file " _YELLOW_("%s"), vkeycnt, path); - - if (datalen) - *datalen = counter; - if (keycnt) - *keycnt = vkeycnt; - out: - free(path); - return retval; -} - -int loadFileDICTIONARY_safe(const char *preferredName, void **pdata, uint8_t keylen, uint32_t *keycnt) { - - int retval = PM3_SUCCESS; - - char *path; - if (searchFile(&path, DICTIONARIES_SUBDIR, preferredName, ".dic", false) != PM3_SUCCESS) - return PM3_EFILE; - - // t5577 == 4bytes - // mifare == 6 bytes - // mf plus == 16 bytes - // mf desfire == 3des3k 24 bytes - // iclass == 8 bytes - // default to 6 bytes. - if (keylen != 4 && keylen != 6 && keylen != 8 && keylen != 16 && keylen != 24) { - keylen = 6; - } - - size_t mem_size; - size_t block_size = 10 * keylen; - - // double up since its chars - keylen <<= 1; - - char line[255]; - - // allocate some space for the dictionary - *pdata = calloc(block_size, sizeof(uint8_t)); - if (*pdata == NULL) { - free(path); - return PM3_EFILE; - } - mem_size = block_size; - - FILE *f = fopen(path, "r"); - if (!f) { - PrintAndLogEx(WARNING, "file not found or locked `" _YELLOW_("%s") "`", path); - retval = PM3_EFILE; - goto out; - } - - // read file - while (fgets(line, sizeof(line), f)) { - - // check if we have enough space (if not allocate more) - if ((*keycnt * (keylen >> 1)) >= mem_size) { - - mem_size += block_size; - *pdata = realloc(*pdata, mem_size); - - if (*pdata == NULL) { - retval = PM3_EFILE; - fclose(f); - goto out; - } else { - memset((uint8_t *)*pdata + (mem_size - block_size), 0, block_size); - } - } - - // add null terminator - line[keylen] = 0; - - // smaller keys than expected is skipped - if (strlen(line) < keylen) - continue; - - // The line start with # is comment, skip - if (line[0] == '#') - continue; - - if (!CheckStringIsHEXValue(line)) - continue; - - uint64_t key = strtoull(line, NULL, 16); - - num_to_bytes(key, keylen >> 1, (uint8_t *)*pdata + (*keycnt * (keylen >> 1))); - - (*keycnt)++; - - memset(line, 0, sizeof(line)); - } - fclose(f); - PrintAndLogEx(SUCCESS, "loaded " _GREEN_("%2d") " keys from dictionary file " _YELLOW_("%s"), *keycnt, path); - - out: - free(path); - return retval; -} - -int loadFileBinaryKey(const char *preferredName, const char *suffix, void **keya, void **keyb, size_t *alen, size_t *blen) { - - char *path; - int res = searchFile(&path, RESOURCES_SUBDIR, preferredName, suffix, false); - if (res != PM3_SUCCESS) { - return PM3_EFILE; - } - - FILE *f = fopen(path, "rb"); - if (!f) { - PrintAndLogEx(WARNING, "file not found or locked `" _YELLOW_("%s") "`", path); - free(path); - return PM3_EFILE; - } - free(path); - - // get filesize in order to malloc memory - fseek(f, 0, SEEK_END); - long fsize = ftell(f); - fseek(f, 0, SEEK_SET); - - if (fsize <= 0) { - PrintAndLogEx(FAILED, "error, when getting filesize"); - fclose(f); - return PM3_EFILE; - } - - // Half is KEY A, half is KEY B - fsize /= 2; - - *keya = calloc(fsize, sizeof(uint8_t)); - if (*keya == NULL) { - PrintAndLogEx(FAILED, "error, cannot allocate memory"); - fclose(f); - return PM3_EMALLOC; - } - - *alen = fread(*keya, 1, fsize, f); - - *keyb = calloc(fsize, sizeof(uint8_t)); - if (*keyb == NULL) { - PrintAndLogEx(FAILED, "error, cannot allocate memory"); - fclose(f); - return PM3_EMALLOC; - } - - *blen = fread(*keyb, 1, fsize, f); - fclose(f); - return PM3_SUCCESS; -} - -static char *my_executable_path = NULL; -static char *my_executable_directory = NULL; - -const char *get_my_executable_path(void) { - return my_executable_path; -} - -char *getExecutableDirectory(const char *path, int *length) { - if (path == NULL || length == NULL) { - return NULL; - } - - const char *last_sep = NULL; - const char *p = path; - - while (*p != '\0') { - if (*p == '\\' || *p == '/') { - last_sep = p; - } - p++; - } - - if (last_sep == NULL) { - *length = 0; - } else { - *length = last_sep - path + 1; - } - - return (char *)last_sep; -} - -static void set_my_executable_path(void) { - char path[1024]; - if (getExecutablePath(path, sizeof(path)) == NULL) { - return; - } - - int path_length = strlen(path); - my_executable_path = (char *)calloc(path_length + 1, sizeof(char)); - int dirname_length = 0; - if (my_executable_path != NULL) { - strncpy(my_executable_path, path, path_length + 1); - if (getExecutableDirectory(my_executable_path, &dirname_length) != NULL) { - my_executable_directory = (char *)calloc(dirname_length + 1, sizeof(char)); - if (my_executable_directory != NULL) { - strncpy(my_executable_directory, my_executable_path, dirname_length); - my_executable_directory[dirname_length] = '\0'; - } - } - } -} - -const char *get_my_executable_directory(void) { - set_my_executable_path(); - return my_executable_directory; -} - -static const char *my_user_directory = NULL; -// static char _cwd_Buffer [FILENAME_MAX] = {0}; - -static void set_my_user_directory(void) { - /* my_user_directory = getenv("HOME"); - - // if not found, default to current directory - if (my_user_directory == NULL) { - my_user_directory = GetCurrentDir(_cwd_Buffer, sizeof(_cwd_Buffer)); - // change all slashes to / (windows should not care... - for (int i = 0; i < strlen(_cwd_Buffer); i++) - if (_cwd_Buffer[i] == '\\') _cwd_Buffer[i] = '/'; - // my_user_directory = "."; - } - */ - my_user_directory = getenv("HOME"); - - // if not found, default to current directory - if (my_user_directory == NULL) { - - uint16_t pathLen = FILENAME_MAX; // should be a good starting point - char *cwd_buffer = (char *)calloc(pathLen, sizeof(uint8_t)); - if (cwd_buffer == NULL) { - PrintAndLogEx(WARNING, "failed to allocate memory"); - return; - } - - getcwd(cwd_buffer, pathLen); - - for (int i = 0; i < strlen(cwd_buffer); i++) { - if (cwd_buffer[i] == '\\') { - cwd_buffer[i] = '/'; - } - } - - my_user_directory = cwd_buffer; - } -} - -const char *get_my_user_directory(void) { - set_my_user_directory(); - return my_user_directory; -} - - - -static int filelist(const char *path, const char *ext, uint8_t last, bool tentative, uint8_t indent, uint16_t strip) { - struct dirent **namelist; - int n; - - n = scandir(path, &namelist, NULL, alphasort); - if (n == -1) { - - if (tentative == false) { - - for (uint8_t j = 0; j < indent; j++) { - PrintAndLogEx(NORMAL, "%s " NOLF, ((last >> j) & 1) ? " " : "│"); - } - PrintAndLogEx(NORMAL, "%s── "_GREEN_("%s"), last ? "└" : "├", &path[strip]); - } - return PM3_EFILE; - } - - for (uint8_t j = 0; j < indent; j++) { - PrintAndLogEx(NORMAL, "%s " NOLF, ((last >> j) & 1) ? " " : "│"); - } - - PrintAndLogEx(NORMAL, "%s── "_GREEN_("%s"), last ? "└" : "├", &path[strip]); - - for (int i = 0; i < n; i++) { - - char tmp_fullpath[1024] = {0}; - strncat(tmp_fullpath, path, sizeof(tmp_fullpath) - 1); - tmp_fullpath[1023] = 0x00; - strncat(tmp_fullpath, namelist[i]->d_name, strlen(tmp_fullpath) - 1); - - if (is_directory(tmp_fullpath)) { - - char newpath[1024]; - if (strcmp(namelist[i]->d_name, ".") == 0 || strcmp(namelist[i]->d_name, "..") == 0) - continue; - - snprintf(newpath, sizeof(newpath), "%s", path); - strncat(newpath, namelist[i]->d_name, sizeof(newpath) - strlen(newpath) - 1); - strncat(newpath, "/", sizeof(newpath) - strlen(newpath) - 1); - - filelist(newpath, ext, last + ((i == n - 1) << (indent + 1)), tentative, indent + 1, strlen(path)); - } else { - - if ((ext == NULL) || ((str_endswith(namelist[i]->d_name, ext)))) { - - for (uint8_t j = 0; j < indent + 1; j++) { - PrintAndLogEx(NORMAL, "%s " NOLF, ((last >> j) & 1) ? " " : "│"); - } - PrintAndLogEx(NORMAL, "%s── %-21s", i == n - 1 ? "└" : "├", namelist[i]->d_name); - } - } - free(namelist[i]); - } - free(namelist); - return PM3_SUCCESS; -} - -int searchAndList(const char *pm3dir, const char *ext) { - // display in same order as searched by searchFile - // try pm3 dirs in current workdir (dev mode) - if (get_my_executable_directory() != NULL) { - char script_directory_path[1024]; - strcpy(script_directory_path, get_my_executable_directory()); - strcat(script_directory_path, pm3dir); - filelist(script_directory_path, ext, false, true, 0, 0); - } - // try pm3 dirs in user .proxmark3 (user mode) - const char *user_path = get_my_user_directory(); - if (user_path != NULL) { - char script_directory_path[1024]; - strcpy(script_directory_path, user_path); - strcat(script_directory_path, PM3_USER_DIRECTORY); - strcat(script_directory_path, pm3dir); - filelist(script_directory_path, ext, false, false, 0, 0); - } - // try pm3 dirs in pm3 installation dir (install mode) - const char *exec_path = get_my_executable_directory(); - if (exec_path != NULL) { - char script_directory_path[1024]; - strcpy(script_directory_path, exec_path); - strcat(script_directory_path, PM3_SHARE_RELPATH); - strcat(script_directory_path, pm3dir); - filelist(script_directory_path, ext, true, false, 0, 0); - } - return PM3_SUCCESS; -} - -static int searchFinalFile(char **foundpath, const char *pm3dir, const char *searchname, bool silent) { - - if ((foundpath == NULL) || (pm3dir == NULL) || (searchname == NULL)) { - return PM3_ESOFT; - } - - // explicit absolute (/) or relative path (./) => try only to match it directly - char *filename = calloc(strlen(searchname) + 1, sizeof(char)); - if (filename == NULL) { - return PM3_EMALLOC; - } - - strcpy(filename, searchname); - if ((g_debugMode == 2) && (!silent)) { - PrintAndLogEx(INFO, "pm3dir...... %s", pm3dir); - PrintAndLogEx(INFO, "Searching... %s", filename); - } - - // try implicit relative path - PrintAndLogEx(DEBUG, "Searching implicit relative paths"); - if (fileExists(filename)) { - *foundpath = filename; - if ((g_debugMode == 2) && (!silent)) { - PrintAndLogEx(INFO, "Found %s", *foundpath); - } - return PM3_SUCCESS; - } - - if (((strlen(filename) > 1) && (filename[0] == '/')) || - ((strlen(filename) > 2) && (filename[0] == '.') && (filename[1] == '/'))) { - goto out; - } - - // try the session paths - PrintAndLogEx(DEBUG, "Searching preferences paths"); - for (int i = 0; i < spItemCount; i++) { - - size_t sn = strlen(g_session.defaultPaths[i]) + strlen(filename) + strlen(PATHSEP) + 1; - char *default_path = calloc(sn, sizeof(char)); - if (default_path == NULL) { - goto out; - } - - snprintf(default_path, sn, "%s%s%s", g_session.defaultPaths[i], PATHSEP, filename); - - if ((g_debugMode == 2) && (!silent)) { - PrintAndLogEx(INFO, "Searching %s", default_path); - } - - if (fileExists(default_path)) { - free(filename); - *foundpath = default_path; - if ((g_debugMode == 2) && (!silent)) { - PrintAndLogEx(INFO, "Found %s", *foundpath); - } - return PM3_SUCCESS; - } else { - free(default_path); - } - } - - // try pm3 dirs in user .proxmark3 (user mode) - PrintAndLogEx(DEBUG, "Searching user .proxmark3 paths"); - const char *user_path = get_my_user_directory(); - if (user_path != NULL) { - char *path = calloc(strlen(user_path) + strlen(PM3_USER_DIRECTORY) + strlen(pm3dir) + strlen(filename) + 1, sizeof(char)); - if (path == NULL) { - goto out; - } - - strcpy(path, user_path); - strcat(path, PM3_USER_DIRECTORY); - strcat(path, pm3dir); - strcat(path, filename); - - if ((g_debugMode == 2) && (!silent)) { - PrintAndLogEx(INFO, "Searching %s", path); - } - - if (fileExists(path)) { - free(filename); - *foundpath = path; - if ((g_debugMode == 2) && (!silent)) { - PrintAndLogEx(INFO, "Found %s", *foundpath); - } - return PM3_SUCCESS; - } else { - free(path); - } - } - - // try pm3 dirs in current client workdir (dev mode) - PrintAndLogEx(DEBUG, "Searching current workdir paths"); - const char *exec_path = get_my_executable_directory(); - if ((exec_path != NULL) && - ((strcmp(DICTIONARIES_SUBDIR, pm3dir) == 0) || - (strcmp(LUA_LIBRARIES_SUBDIR, pm3dir) == 0) || - (strcmp(LUA_SCRIPTS_SUBDIR, pm3dir) == 0) || - (strcmp(CMD_SCRIPTS_SUBDIR, pm3dir) == 0) || - (strcmp(PYTHON_SCRIPTS_SUBDIR, pm3dir) == 0) || - (strcmp(RESOURCES_SUBDIR, pm3dir) == 0))) { - char *path = calloc(strlen(exec_path) + strlen(pm3dir) + strlen(filename) + 1, sizeof(char)); - if (path == NULL) { - goto out; - } - - strcpy(path, exec_path); - strcat(path, pm3dir); - strcat(path, filename); - - if ((g_debugMode == 2) && (!silent)) { - PrintAndLogEx(INFO, "Searching %s", path); - } - - if (fileExists(path)) { - free(filename); - *foundpath = path; - if ((g_debugMode == 2) && (!silent)) { - PrintAndLogEx(INFO, "Found %s", *foundpath); - } - return PM3_SUCCESS; - } else { - free(path); - } - } - - // try pm3 dirs in current repo workdir (dev mode) - PrintAndLogEx(DEBUG, "Searching PM3 dirs in current workdir"); - if ((exec_path != NULL) && - ((strcmp(TRACES_SUBDIR, pm3dir) == 0) || - (strcmp(FIRMWARES_SUBDIR, pm3dir) == 0) || - (strcmp(BOOTROM_SUBDIR, pm3dir) == 0) || - (strcmp(FULLIMAGE_SUBDIR, pm3dir) == 0))) { - char *path = calloc(strlen(exec_path) + strlen(ABOVE) + strlen(pm3dir) + strlen(filename) + 1, sizeof(char)); - if (path == NULL) { - goto out; - } - - strcpy(path, exec_path); - strcat(path, ABOVE); - strcat(path, pm3dir); - strcat(path, filename); - - if ((g_debugMode == 2) && (!silent)) { - PrintAndLogEx(INFO, "Searching %s", path); - } - - if (fileExists(path)) { - free(filename); - *foundpath = path; - if ((g_debugMode == 2) && (!silent)) { - PrintAndLogEx(INFO, "Found %s", *foundpath); - } - return PM3_SUCCESS; - } else { - free(path); - } - } - - // try pm3 dirs in pm3 installation dir (install mode) - PrintAndLogEx(DEBUG, "Searching PM3 installation dir paths"); - if (exec_path != NULL) { - char *path = calloc(strlen(exec_path) + strlen(PM3_SHARE_RELPATH) + strlen(pm3dir) + strlen(filename) + 1, sizeof(char)); - if (path == NULL) { - goto out; - } - - strcpy(path, exec_path); - strcat(path, PM3_SHARE_RELPATH); - strcat(path, pm3dir); - strcat(path, filename); - - if ((g_debugMode == 2) && (!silent)) { - PrintAndLogEx(INFO, "Searching %s", path); - } - - if (fileExists(path)) { - free(filename); - *foundpath = path; - if ((g_debugMode == 2) && (!silent)) { - PrintAndLogEx(INFO, "Found %s", *foundpath); - } - return PM3_SUCCESS; - } else { - free(path); - } - } - out: - free(filename); - return PM3_EFILE; -} - -int searchFile(char **foundpath, const char *pm3dir, const char *searchname, const char *suffix, bool silent) { - - if (foundpath == NULL) - return PM3_EINVARG; - - if (searchname == NULL || strlen(searchname) == 0) - return PM3_EINVARG; - - if (is_directory(searchname)) - return PM3_EINVARG; - - char *filename = filenamemcopy(searchname, suffix); - if (filename == NULL) - return PM3_EMALLOC; - - if (strlen(filename) == 0) { - free(filename); - return PM3_EFILE; - } - - int res = searchFinalFile(foundpath, pm3dir, filename, silent); - if (res != PM3_SUCCESS) { - if ((res == PM3_EFILE) && (!silent)) { - PrintAndLogEx(FAILED, "Error - can't find `" _YELLOW_("%s") "`", filename); - } - } - free(filename); - return res; -} - -int pm3_load_dump(const char *fn, void **pdump, size_t *dumplen, size_t maxdumplen) { - - int res = 0; - DumpFileType_t dftype = getfiletype(fn); - switch (dftype) { - case BIN: { - res = loadFile_safe(fn, ".bin", pdump, dumplen); - break; - } - case EML: { - res = loadFileEML_safe(fn, pdump, dumplen); - break; - } - case JSON: { - *pdump = calloc(maxdumplen, sizeof(uint8_t)); - if (*pdump == NULL) { - PrintAndLogEx(WARNING, "Fail, cannot allocate memory"); - return PM3_EMALLOC; - } - break; - } - case DICTIONARY: { - PrintAndLogEx(ERR, "Error: Only BIN/EML/JSON formats allowed"); - return PM3_EINVARG; - } - } - - if (res != PM3_SUCCESS) { - PrintAndLogEx(WARNING, "file not found or locked `" _YELLOW_("%s") "`", fn); - return PM3_EFILE; - } - - return res; -} - -int pm3_save_dump(const char *fn, uint8_t *d, size_t n, JSONFileType jsft, size_t blocksize) { - - if (d == NULL || n == 0) { - PrintAndLogEx(INFO, "No data to save, skipping..."); - return PM3_EINVARG; - } - - saveFile(fn, ".bin", d, n); - saveFileEML(fn, d, n, blocksize); - return PM3_SUCCESS; -} diff --git a/HardNestedSolver/pm3/fileutils.h b/HardNestedSolver/pm3/fileutils.h deleted file mode 100755 index b501a31..0000000 --- a/HardNestedSolver/pm3/fileutils.h +++ /dev/null @@ -1,263 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// See LICENSE.txt for the text of the license. -//----------------------------------------------------------------------------- - -#ifndef FILEUTILS_H -#define FILEUTILS_H - -#include -#include -#include -#include -#include -#include -#include "ui.h" - -typedef enum { - jsfRaw, - jsfCardMemory, - jsfMfuMemory, - jsfHitag, - jsfIclass, - jsf14b, - jsf15, - jsfLegic, - jsfT55x7, - jsfT5555, - jsfMfPlusKeys, - jsfCustom, - jsfMfDesfireKeys, - jsfEM4x05, - jsfEM4x69, - jsfEM4x50, - jsfFido, - jsfFudan, - jsfTopaz, -} JSONFileType; - -typedef enum { - BIN = 0, - EML, - JSON, - DICTIONARY, -} DumpFileType_t; - -int fileExists(const char *filename); -//bool create_path(const char *dirname); - -// set a path in the path list g_session.defaultPaths -bool setDefaultPath(savePaths_t pathIndex, const char *path); - -char *newfilenamemcopy(const char *preferredName, const char *suffix); - -/** - * @brief Utility function to save data to a binary file. This method takes a preferred name, but if that - * file already exists, it tries with another name until it finds something suitable. - * E.g. dumpdata-15.txt - * - * @param preferredName - * @param suffix the file suffix. Including the ".". - * @param data The binary data to write to the file - * @param datalen the length of the data - * @return 0 for ok, 1 for failz - */ -int saveFile(const char *preferredName, const char *suffix, const void *data, size_t datalen); - -/** - * @brief Utility function to save data to a textfile (EML). This method takes a preferred name, but if that - * file already exists, it tries with another name until it finds something suitable. - * E.g. dumpdata-15.txt - * - * @param preferredName - * @param data The binary data to write to the file - * @param datalen the length of the data - * @param blocksize the length of one row - * @return 0 for ok, 1 for failz -*/ -int saveFileEML(const char *preferredName, uint8_t *data, size_t datalen, size_t blocksize); - -/** STUB - * @brief Utility function to save WAVE data to a file. This method takes a preferred name, but if that - * file already exists, it tries with another name until it finds something suitable. - * E.g. dumpdata-15.wav - * - * @param preferredName - * @param data The binary data to write to the file - * @param datalen the length of the data - * @return 0 for ok - */ -int saveFileWAVE(const char *preferredName, const int *data, size_t datalen); - -/** STUB - * @brief Utility function to save PM3 data to a file. This method takes a preferred name, but if that - * file already exists, it tries with another name until it finds something suitable. - * E.g. dump_trace.pm3_old - * - * @param preferredName - * @param data The binary data to write to the file - * @param datalen the length of the data - * @return 0 for ok - */ -int saveFilePM3(const char *preferredName, int *data, size_t datalen); - -/** - * @brief Utility function to save a keydump into a binary file. - * - * @param preferredName - * @param sectorsCnt the used sectors - * @param e_sector the keys in question - * @return 0 for ok, 1 for failz - */ -int createMfcKeyDump(const char *preferredName, uint8_t sectorsCnt, sector_t *e_sector); - -/** - * @brief Utility function to load data from a binary file. This method takes a preferred name. - * E.g. dumpdata-15.bin - * - * @param preferredName - * @param suffix the file suffix. Including the ".". - * @param data The data array to store the loaded bytes from file - * @param maxdatalen the number of bytes that your data array has - * @param datalen the number of bytes loaded from file - * @return PM3_SUCCESS for ok, PM3_E* for failz -*/ -int loadFile(const char *preferredName, const char *suffix, void *data, size_t maxdatalen, size_t *datalen); - - -/** - * @brief Utility function to load data from a binary file. This method takes a preferred name. - * E.g. dumpdata-15.bin, tries to search for it, and allocated memory. - * - * @param preferredName - * @param suffix the file suffix. Including the ".". - * @param data The data array to store the loaded bytes from file - * @param datalen the number of bytes loaded from file - * @return PM3_SUCCESS for ok, PM3_E* for failz -*/ -int loadFile_safe(const char *preferredName, const char *suffix, void **pdata, size_t *datalen); -int loadFile_safeEx(const char *preferredName, const char *suffix, void **pdata, size_t *datalen, bool verbose); -/** - * @brief Utility function to load data from a textfile (EML). This method takes a preferred name. - * E.g. dumpdata-15.txt - * - * @param preferredName - * @param data The data array to store the loaded bytes from file - * @param datalen the number of bytes loaded from file - * @return 0 for ok, 1 for failz -*/ -int loadFileEML(const char *preferredName, void *data, size_t *datalen); -int loadFileEML_safe(const char *preferredName, void **pdata, size_t *datalen); - -/** - * @brief Utility function to load data from a DICTIONARY textfile. This method takes a preferred name. - * E.g. mfc_default_keys.dic - * - * @param preferredName - * @param data The data array to store the loaded bytes from file - * @param datalen the number of bytes loaded from file. may be NULL - * @param keylen the number of bytes a key per row is - * @param keycnt key count that lays in data. may be NULL - * @return 0 for ok, 1 for failz -*/ -int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, uint8_t keylen, uint32_t *keycnt); - -/** - * @brief Utility function to load data from a DICTIONARY textfile. This method takes a preferred name. - * E.g. mfc_default_keys.dic - * can be executed several times for big dictionaries and checks length of buffer - * - * @param preferredName - * @param data The data array to store the loaded bytes from file - * @param maxdatalen maximum size of data array in bytes - * @param datalen the number of bytes loaded from file. may be NULL - * @param keylen the number of bytes a key per row is - * @param keycnt key count that lays in data. may be NULL - * @param startFilePosition start position in dictionary file. used for big dictionaries. - * @param endFilePosition in case we have keys in file and maxdatalen reached it returns current key position in file. may be NULL - * @param verbose print messages if true - * @return 0 for ok, 1 for failz -*/ -int loadFileDICTIONARYEx(const char *preferredName, void *data, size_t maxdatalen, size_t *datalen, uint8_t keylen, uint32_t *keycnt, - size_t startFilePosition, size_t *endFilePosition, bool verbose); - -/** - * @brief Utility function to load data safely from a DICTIONARY textfile. This method takes a preferred name. - * E.g. mfc_default_keys.dic - * - * @param preferredName - * @param pdata A pointer to a pointer (for reverencing the loaded dictionary) - * @param keylen the number of bytes a key per row is - * @return 0 for ok, 1 for failz -*/ -int loadFileDICTIONARY_safe(const char *preferredName, void **pdata, uint8_t keylen, uint32_t *keycnt); - -int loadFileBinaryKey(const char *preferredName, const char *suffix, void **keya, void **keyb, size_t *alen, size_t *blen); - -typedef enum { - MFU_DF_UNKNOWN, - MFU_DF_PLAINBIN, - MFU_DF_OLDBIN, - MFU_DF_NEWBIN -} mfu_df_e; -/** - * @brief Utility function to check and convert plain mfu dump format to new mfu binary format. - * plain dumps doesn't have any extra data, like version, signature etc. - * @param dump pointer to loaded dump to check and convert format - * @param dumplen the number of bytes loaded dump and converted - * @param verbose - extra debug output - * @return PM3_SUCCESS for ok, PM3_ESOFT for fails -*/ -int convert_mfu_dump_format(uint8_t **dump, size_t *dumplen, bool verbose); -mfu_df_e detect_mfu_dump_format(uint8_t **dump, size_t *dumplen, bool verbose); - -int searchAndList(const char *pm3dir, const char *ext); -int searchFile(char **foundpath, const char *pm3dir, const char *searchname, const char *suffix, bool silent); - - -/** - * @brief detects if file is of a supported filetype based on extension - * @param filename - * @return - */ -DumpFileType_t getfiletype(const char *filename); - - -/** - * @brief load dump file into a data array dynamically allocated - * @param fn - * @param pdump pointer to loaded dump - * @param dumplen the number of bytes loaded from dump file - * @param maxdumplen maximum size of data array in bytes (JSON files) - * @return PM3_SUCCESS if OK - */ -int pm3_load_dump(const char *fn, void **pdump, size_t *dumplen, size_t maxdumplen); - - -/** STUB - * @brief Utility function to save data to three file files (BIN/EML/JSON). - * It also tries to save according to user preferences set dump folder paths. - * E.g. dumpdata.bin - * E.g. dumpdata.eml - * E.g. dumpdata.json - - * @param fn - * @param d The binary data to write to the file - * @param n the length of the data - * @param jsft json format type for the different memory cards (MFC, MFUL, LEGIC, 14B, 15, ICLASS etc) - * @param blocksize - * @return PM3_SUCCESS if OK - */ -int pm3_save_dump(const char *fn, uint8_t *d, size_t n, JSONFileType jsft, size_t blocksize); -#endif // FILEUTILS_H diff --git a/HardNestedSolver/pm3/pm3_cmd.h b/HardNestedSolver/pm3/pm3_cmd.h deleted file mode 100755 index ceccada..0000000 --- a/HardNestedSolver/pm3/pm3_cmd.h +++ /dev/null @@ -1,543 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// See LICENSE.txt for the text of the license. -//----------------------------------------------------------------------------- -// Definitions for all the types of commands that may be sent over USB; our -// own protocol. -//----------------------------------------------------------------------------- - -#ifndef __PM3_CMD_H -#define __PM3_CMD_H - -#include "common.h" - -// Use it e.g. when using slow links such as BT -#define USART_SLOW_LINK - -#define PM3_CMD_DATA_SIZE 512 -#define PM3_CMD_DATA_SIZE_MIX ( PM3_CMD_DATA_SIZE - 3 * sizeof(uint64_t) ) - -// For the bootloader -#define CMD_DEVICE_INFO 0x0000 -//#define CMD_SETUP_WRITE 0x0001 -#define CMD_FINISH_WRITE 0x0003 -#define CMD_HARDWARE_RESET 0x0004 -#define CMD_START_FLASH 0x0005 -#define CMD_CHIP_INFO 0x0006 -#define CMD_BL_VERSION 0x0007 -#define CMD_NACK 0x00fe -#define CMD_ACK 0x00ff - -// For general mucking around -#define CMD_DEBUG_PRINT_STRING 0x0100 -#define CMD_DEBUG_PRINT_INTEGERS 0x0101 -#define CMD_DEBUG_PRINT_BYTES 0x0102 -#define CMD_LCD_RESET 0x0103 -#define CMD_LCD 0x0104 -#define CMD_BUFF_CLEAR 0x0105 -#define CMD_READ_MEM 0x0106 -#define CMD_VERSION 0x0107 -#define CMD_STATUS 0x0108 -#define CMD_PING 0x0109 -#define CMD_DOWNLOAD_EML_BIGBUF 0x0110 -#define CMD_DOWNLOADED_EML_BIGBUF 0x0111 -#define CMD_CAPABILITIES 0x0112 -#define CMD_QUIT_SESSION 0x0113 -#define CMD_SET_DBGMODE 0x0114 -#define CMD_STANDALONE 0x0115 -#define CMD_WTX 0x0116 -#define CMD_TIA 0x0117 -#define CMD_BREAK_LOOP 0x0118 -#define CMD_SET_TEAROFF 0x0119 -#define CMD_GET_DBGMODE 0x0120 - -// RDV40, Flash memory operations -#define CMD_FLASHMEM_WRITE 0x0121 -#define CMD_FLASHMEM_WIPE 0x0122 -#define CMD_FLASHMEM_DOWNLOAD 0x0123 -#define CMD_FLASHMEM_DOWNLOADED 0x0124 -#define CMD_FLASHMEM_INFO 0x0125 -#define CMD_FLASHMEM_SET_SPIBAUDRATE 0x0126 - -// RDV40, High level flashmem SPIFFS Manipulation -// ALL function will have a lazy or Safe version -// that will be handled as argument of safety level [0..2] respectiveley normal / lazy / safe -// However as how design is, MOUNT and UNMOUNT only need/have lazy as safest level so a safe level will still execute a lazy version -// see spiffs.c for more about the normal/lazy/safety information) -#define CMD_SPIFFS_MOUNT 0x0130 -#define CMD_SPIFFS_UNMOUNT 0x0131 -#define CMD_SPIFFS_WRITE 0x0132 - -// We take +0x1000 when having a variant of similar function (todo : make it an argument!) -#define CMD_SPIFFS_APPEND 0x1132 - -#define CMD_SPIFFS_READ 0x0133 -//We use no open/close instruction, as they are handled internally. -#define CMD_SPIFFS_REMOVE 0x0134 -#define CMD_SPIFFS_RM CMD_SPIFFS_REMOVE -#define CMD_SPIFFS_RENAME 0x0135 -#define CMD_SPIFFS_MV CMD_SPIFFS_RENAME -#define CMD_SPIFFS_COPY 0x0136 -#define CMD_SPIFFS_CP CMD_SPIFFS_COPY -#define CMD_SPIFFS_STAT 0x0137 -#define CMD_SPIFFS_FSTAT 0x0138 -#define CMD_SPIFFS_INFO 0x0139 -#define CMD_SPIFFS_FORMAT CMD_FLASHMEM_WIPE - -#define CMD_SPIFFS_WIPE 0x013A - -// This take a +0x2000 as they are high level helper and special functions -// As the others, they may have safety level argument if it makes sense -#define CMD_SPIFFS_PRINT_TREE 0x2130 -#define CMD_SPIFFS_GET_TREE 0x2131 -#define CMD_SPIFFS_TEST 0x2132 -#define CMD_SPIFFS_PRINT_FSINFO 0x2133 -#define CMD_SPIFFS_DOWNLOAD 0x2134 -#define CMD_SPIFFS_DOWNLOADED 0x2135 -#define CMD_SPIFFS_ELOAD 0x2136 -#define CMD_SPIFFS_CHECK 0x3000 - -// RDV40, Smart card operations -#define CMD_SMART_RAW 0x0140 -#define CMD_SMART_UPGRADE 0x0141 -#define CMD_SMART_UPLOAD 0x0142 -#define CMD_SMART_ATR 0x0143 -#define CMD_SMART_SETBAUD 0x0144 -#define CMD_SMART_SETCLOCK 0x0145 - -// RDV40, FPC USART -#define CMD_USART_RX 0x0160 -#define CMD_USART_TX 0x0161 -#define CMD_USART_TXRX 0x0162 -#define CMD_USART_CONFIG 0x0163 - -// For low-frequency tags -#define CMD_LF_TI_READ 0x0202 -#define CMD_LF_TI_WRITE 0x0203 -#define CMD_LF_ACQ_RAW_ADC 0x0205 -#define CMD_LF_MOD_THEN_ACQ_RAW_ADC 0x0206 -#define CMD_DOWNLOAD_BIGBUF 0x0207 -#define CMD_DOWNLOADED_BIGBUF 0x0208 -#define CMD_LF_UPLOAD_SIM_SAMPLES 0x0209 -#define CMD_LF_SIMULATE 0x020A -#define CMD_LF_HID_WATCH 0x020B -#define CMD_LF_HID_SIMULATE 0x020C -#define CMD_LF_SET_DIVISOR 0x020D -#define CMD_LF_SIMULATE_BIDIR 0x020E -#define CMD_SET_ADC_MUX 0x020F -#define CMD_LF_HID_CLONE 0x0210 -#define CMD_LF_EM410X_CLONE 0x0211 -#define CMD_LF_T55XX_READBL 0x0214 -#define CMD_LF_T55XX_WRITEBL 0x0215 -#define CMD_LF_T55XX_RESET_READ 0x0216 -#define CMD_LF_PCF7931_READ 0x0217 -#define CMD_LF_PCF7931_WRITE 0x0223 -#define CMD_LF_EM4X_LOGIN 0x0229 -#define CMD_LF_EM4X_READWORD 0x0218 -#define CMD_LF_EM4X_WRITEWORD 0x0219 -#define CMD_LF_EM4X_PROTECTWORD 0x021B -#define CMD_LF_EM4X_BF 0x022A -#define CMD_LF_IO_WATCH 0x021A -#define CMD_LF_EM410X_WATCH 0x021C -#define CMD_LF_EM4X50_INFO 0x0240 -#define CMD_LF_EM4X50_WRITE 0x0241 -#define CMD_LF_EM4X50_WRITEPWD 0x0242 -#define CMD_LF_EM4X50_READ 0x0243 -#define CMD_LF_EM4X50_BRUTE 0x0245 -#define CMD_LF_EM4X50_LOGIN 0x0246 -#define CMD_LF_EM4X50_SIM 0x0250 -#define CMD_LF_EM4X50_READER 0x0251 -#define CMD_LF_EM4X50_ESET 0x0252 -#define CMD_LF_EM4X50_CHK 0x0253 -#define CMD_LF_EM4X70_INFO 0x0260 -#define CMD_LF_EM4X70_WRITE 0x0261 -#define CMD_LF_EM4X70_UNLOCK 0x0262 -#define CMD_LF_EM4X70_AUTH 0x0263 -#define CMD_LF_EM4X70_WRITEPIN 0x0264 -#define CMD_LF_EM4X70_WRITEKEY 0x0265 -#define CMD_LF_EM4X70_BRUTE 0x0266 -// Sampling configuration for LF reader/sniffer -#define CMD_LF_SAMPLING_SET_CONFIG 0x021D -#define CMD_LF_FSK_SIMULATE 0x021E -#define CMD_LF_ASK_SIMULATE 0x021F -#define CMD_LF_PSK_SIMULATE 0x0220 -#define CMD_LF_NRZ_SIMULATE 0x0232 -#define CMD_LF_AWID_WATCH 0x0221 -#define CMD_LF_VIKING_CLONE 0x0222 -#define CMD_LF_T55XX_WAKEUP 0x0224 -#define CMD_LF_COTAG_READ 0x0225 -#define CMD_LF_T55XX_SET_CONFIG 0x0226 -#define CMD_LF_SAMPLING_PRINT_CONFIG 0x0227 -#define CMD_LF_SAMPLING_GET_CONFIG 0x0228 - -#define CMD_LF_T55XX_CHK_PWDS 0x0230 -#define CMD_LF_T55XX_DANGERRAW 0x0231 - - -// ZX8211 -#define CMD_LF_ZX_READ 0x0270 -#define CMD_LF_ZX_WRITE 0x0271 - -/* CMD_SET_ADC_MUX: ext1 is 0 for lopkd, 1 for loraw, 2 for hipkd, 3 for hiraw */ - -// For the 13.56 MHz tags -#define CMD_HF_ISO15693_ACQ_RAW_ADC 0x0300 -#define CMD_HF_ACQ_RAW_ADC 0x0301 -#define CMD_HF_SRI_READ 0x0303 -#define CMD_HF_ISO14443B_COMMAND 0x0305 -#define CMD_HF_ISO15693_READER 0x0310 -#define CMD_HF_ISO15693_SIMULATE 0x0311 -#define CMD_HF_ISO15693_SNIFF 0x0312 -#define CMD_HF_ISO15693_COMMAND 0x0313 -#define CMD_HF_ISO15693_FINDAFI 0x0315 -#define CMD_HF_ISO15693_CSETUID 0x0316 -#define CMD_HF_ISO15693_SLIX_ENABLE_PRIVACY 0x0867 -#define CMD_HF_ISO15693_SLIX_DISABLE_PRIVACY 0x0317 -#define CMD_HF_ISO15693_SLIX_DISABLE_EAS 0x0318 -#define CMD_HF_ISO15693_SLIX_ENABLE_EAS 0x0862 -#define CMD_HF_ISO15693_SLIX_PASS_PROTECT_AFI 0x0863 -#define CMD_HF_ISO15693_SLIX_PASS_PROTECT_EAS 0x0864 -#define CMD_HF_ISO15693_SLIX_WRITE_PWD 0x0865 -#define CMD_HF_ISO15693_WRITE_AFI 0x0866 -#define CMD_HF_TEXKOM_SIMULATE 0x0320 -#define CMD_HF_ISO15693_EML_CLEAR 0x0330 -#define CMD_HF_ISO15693_EML_SETMEM 0x0331 - -#define CMD_LF_SNIFF_RAW_ADC 0x0360 - -// For Hitag2 transponders -#define CMD_LF_HITAG_SNIFF 0x0370 -#define CMD_LF_HITAG_SIMULATE 0x0371 -#define CMD_LF_HITAG_READER 0x0372 - -// For HitagS -#define CMD_LF_HITAGS_TEST_TRACES 0x0367 -#define CMD_LF_HITAGS_SIMULATE 0x0368 -#define CMD_LF_HITAGS_READ 0x0373 -#define CMD_LF_HITAGS_WRITE 0x0375 - -#define CMD_LF_HITAG_ELOAD 0x0376 - -#define CMD_HF_ISO14443A_ANTIFUZZ 0x0380 -#define CMD_HF_ISO14443B_SIMULATE 0x0381 -#define CMD_HF_ISO14443B_SNIFF 0x0382 - -#define CMD_HF_ISO14443A_SNIFF 0x0383 -#define CMD_HF_ISO14443A_SIMULATE 0x0384 - -#define CMD_HF_ISO14443A_READER 0x0385 - -#define CMD_HF_LEGIC_SIMULATE 0x0387 -#define CMD_HF_LEGIC_READER 0x0388 -#define CMD_HF_LEGIC_WRITER 0x0389 - -#define CMD_HF_EPA_COLLECT_NONCE 0x038A -#define CMD_HF_EPA_REPLAY 0x038B -#define CMD_HF_EPA_PACE_SIMULATE 0x039C - -#define CMD_HF_LEGIC_INFO 0x03BC -#define CMD_HF_LEGIC_ESET 0x03BD - -// iCLASS / Picopass -#define CMD_HF_ICLASS_READCHECK 0x038F -#define CMD_HF_ICLASS_DUMP 0x0391 -#define CMD_HF_ICLASS_SNIFF 0x0392 -#define CMD_HF_ICLASS_SIMULATE 0x0393 -#define CMD_HF_ICLASS_READER 0x0394 -#define CMD_HF_ICLASS_READBL 0x0396 -#define CMD_HF_ICLASS_WRITEBL 0x0397 -#define CMD_HF_ICLASS_EML_MEMSET 0x0398 -#define CMD_HF_ICLASS_CHKKEYS 0x039A -#define CMD_HF_ICLASS_RESTORE 0x039B - -// For ISO1092 / FeliCa -#define CMD_HF_FELICA_SIMULATE 0x03A0 -#define CMD_HF_FELICA_SNIFF 0x03A1 -#define CMD_HF_FELICA_COMMAND 0x03A2 -//temp -#define CMD_HF_FELICALITE_DUMP 0x03AA -#define CMD_HF_FELICALITE_SIMULATE 0x03AB - -// For 14a config -#define CMD_HF_ISO14443A_PRINT_CONFIG 0x03B0 -#define CMD_HF_ISO14443A_GET_CONFIG 0x03B1 -#define CMD_HF_ISO14443A_SET_CONFIG 0x03B2 - -// For measurements of the antenna tuning -#define CMD_MEASURE_ANTENNA_TUNING 0x0400 -#define CMD_MEASURE_ANTENNA_TUNING_HF 0x0401 -#define CMD_MEASURE_ANTENNA_TUNING_LF 0x0402 -#define CMD_LISTEN_READER_FIELD 0x0420 -#define CMD_HF_DROPFIELD 0x0430 - -// For direct FPGA control -#define CMD_FPGA_MAJOR_MODE_OFF 0x0500 - -// For mifare commands -#define CMD_HF_MIFARE_EML_MEMCLR 0x0601 -#define CMD_HF_MIFARE_EML_MEMSET 0x0602 -#define CMD_HF_MIFARE_EML_MEMGET 0x0603 -#define CMD_HF_MIFARE_EML_LOAD 0x0604 - -// magic chinese card commands -#define CMD_HF_MIFARE_CSETBL 0x0605 -#define CMD_HF_MIFARE_CGETBL 0x0606 -#define CMD_HF_MIFARE_CIDENT 0x0607 - -#define CMD_HF_MIFARE_SIMULATE 0x0610 - -#define CMD_HF_MIFARE_READER 0x0611 -#define CMD_HF_MIFARE_NESTED 0x0612 -#define CMD_HF_MIFARE_ACQ_ENCRYPTED_NONCES 0x0613 -#define CMD_HF_MIFARE_ACQ_NONCES 0x0614 -#define CMD_HF_MIFARE_STATIC_NESTED 0x0615 - -#define CMD_HF_MIFARE_READBL 0x0620 -#define CMD_HF_MIFAREU_READBL 0x0720 -#define CMD_HF_MIFARE_READSC 0x0621 -#define CMD_HF_MIFAREU_READCARD 0x0721 -#define CMD_HF_MIFARE_WRITEBL 0x0622 -#define CMD_HF_MIFARE_VALUE 0x0627 -#define CMD_HF_MIFAREU_WRITEBL 0x0722 -#define CMD_HF_MIFAREU_WRITEBL_COMPAT 0x0723 - -#define CMD_HF_MIFARE_CHKKEYS 0x0623 -#define CMD_HF_MIFARE_SETMOD 0x0624 -#define CMD_HF_MIFARE_CHKKEYS_FAST 0x0625 -#define CMD_HF_MIFARE_CHKKEYS_FILE 0x0626 - -#define CMD_HF_MIFARE_SNIFF 0x0630 -#define CMD_HF_MIFARE_MFKEY 0x0631 -#define CMD_HF_MIFARE_PERSONALIZE_UID 0x0632 - -//ultralightC -#define CMD_HF_MIFAREUC_AUTH 0x0724 -//0x0725 and 0x0726 no longer used -#define CMD_HF_MIFAREUC_SETPWD 0x0727 - -// mifare desfire -#define CMD_HF_DESFIRE_READBL 0x0728 -#define CMD_HF_DESFIRE_WRITEBL 0x0729 -#define CMD_HF_DESFIRE_AUTH1 0x072a -#define CMD_HF_DESFIRE_AUTH2 0x072b -#define CMD_HF_DESFIRE_READER 0x072c -#define CMD_HF_DESFIRE_INFO 0x072d -#define CMD_HF_DESFIRE_COMMAND 0x072e - -#define CMD_HF_MIFARE_NACK_DETECT 0x0730 -#define CMD_HF_MIFARE_STATIC_NONCE 0x0731 - -// MFU OTP TearOff -#define CMD_HF_MFU_OTP_TEAROFF 0x0740 -// MFU_Ev1 Counter TearOff -#define CMD_HF_MFU_COUNTER_TEAROFF 0x0741 - - -#define CMD_HF_SNIFF 0x0800 -#define CMD_HF_PLOT 0x0801 - -// Fpga plot download -#define CMD_FPGAMEM_DOWNLOAD 0x0802 -#define CMD_FPGAMEM_DOWNLOADED 0x0803 - -// For ThinFilm Kovio -#define CMD_HF_THINFILM_READ 0x0810 -#define CMD_HF_THINFILM_SIMULATE 0x0811 - -//For Atmel CryptoRF -#define CMD_HF_CRYPTORF_SIM 0x0820 - -// Gen 3 magic cards -#define CMD_HF_MIFARE_GEN3UID 0x0850 -#define CMD_HF_MIFARE_GEN3BLK 0x0851 -#define CMD_HF_MIFARE_GEN3FREEZ 0x0852 - -// Gen 4 GTU magic cards -#define CMD_HF_MIFARE_G4_RDBL 0x0860 -#define CMD_HF_MIFARE_G4_WRBL 0x0861 - -// Gen 4 GDM magic cards -#define CMD_HF_MIFARE_G4_GDM_RDBL 0x0870 -#define CMD_HF_MIFARE_G4_GDM_WRBL 0x0871 -#define CMD_HF_MIFARE_G4_GDM_CONFIG 0x0872 -#define CMD_HF_MIFARE_G4_GDM_WRCFG 0x0873 - -#define CMD_UNKNOWN 0xFFFF - -//Mifare simulation flags -#define FLAG_INTERACTIVE 0x01 -#define FLAG_4B_UID_IN_DATA 0x02 -#define FLAG_7B_UID_IN_DATA 0x04 -#define FLAG_10B_UID_IN_DATA 0x08 -#define FLAG_UID_IN_EMUL 0x10 -#define FLAG_NR_AR_ATTACK 0x20 -#define FLAG_MF_MINI 0x80 -#define FLAG_MF_1K 0x100 -#define FLAG_MF_2K 0x200 -#define FLAG_MF_4K 0x400 -#define FLAG_FORCED_ATQA 0x800 -#define FLAG_FORCED_SAK 0x1000 -#define FLAG_CVE21_0430 0x2000 - - -#define MODE_SIM_CSN 0 -#define MODE_EXIT_AFTER_MAC 1 -#define MODE_FULLSIM 2 - -// Static Nonce detection -#define NONCE_FAIL 0x01 -#define NONCE_NORMAL 0x02 -#define NONCE_STATIC 0x03 - -// Dbprintf flags -#define FLAG_RAWPRINT 0x00 -#define FLAG_LOG 0x01 -#define FLAG_NEWLINE 0x02 -#define FLAG_INPLACE 0x04 -#define FLAG_ANSI 0x08 - -// Error codes Usages: - -// Success, regular quit -#define PM3_SQUIT 2 -// Success, transfer nonces pm3_old: Sending nonces back to client -#define PM3_SNONCES 1 -// Success (no error) -#define PM3_SUCCESS 0 - -// Undefined error -#define PM3_EUNDEF -1 -// Invalid argument(s) client: user input parsing -#define PM3_EINVARG -2 -// Operation not supported by device client/pm3_old: probably only on pm3_old once client becomes universal -#define PM3_EDEVNOTSUPP -3 -// Operation timed out client: no response in time from pm3_old -#define PM3_ETIMEOUT -4 -// Operation aborted (by user) client/pm3_old: kbd/button pressed -#define PM3_EOPABORTED -5 -// Not (yet) implemented client/pm3_old: TBD place holder -#define PM3_ENOTIMPL -6 -// Error while RF transmission client/pm3_old: fail between pm3_old & card -#define PM3_ERFTRANS -7 -// Input / output error pm3_old: error in client frame reception -#define PM3_EIO -8 -// Buffer overflow client/pm3_old: specified buffer too large for the operation -#define PM3_EOVFLOW -9 -// Software error client/pm3_old: e.g. error in parsing some data -#define PM3_ESOFT -10 -// Flash error client/pm3_old: error in RDV4 Flash operation -#define PM3_EFLASH -11 -// Memory allocation error client: error in memory allocation (maybe also for pm3_old BigBuff?) -#define PM3_EMALLOC -12 -// File error client: error related to file access on host -#define PM3_EFILE -13 -// Generic TTY error -#define PM3_ENOTTY -14 -// Initialization error pm3_old: error related to trying to initialize the pm3_old / fpga for different operations -#define PM3_EINIT -15 -// Expected a different answer error client/pm3_old: error when expecting one answer and got another one -#define PM3_EWRONGANSWER -16 -// Memory out-of-bounds error client/pm3_old: error when a read/write is outside the expected array -#define PM3_EOUTOFBOUND -17 -// exchange with card error client/pm3_old: error when cant get answer from card or got an incorrect answer -#define PM3_ECARDEXCHANGE -18 - -// Failed to create APDU, -#define PM3_EAPDU_ENCODEFAIL -19 -// APDU responded with a failure code -#define PM3_EAPDU_FAIL -20 - -// execute pm3_old cmd failed client/pm3_old: when one of our pm3_old cmd tries and fails. opposite from PM3_SUCCESS -#define PM3_EFAILED -21 -// partial success client/pm3_old: when trying to dump a tag and fails on some blocks. Partial dump. -#define PM3_EPARTIAL -22 -// tearoff occurred client/pm3_old: when a tearoff hook was called and a tearoff actually happened -#define PM3_ETEAROFF -23 - -// Got bad CRC client/pm3_old: error in transfer of data, crc mismatch. -#define PM3_ECRC -24 - -// STATIC Nonce detect pm3_old: when collecting nonces for hardnested -#define PM3_ESTATIC_NONCE -25 - -// No data pm3_old: no data available, no host frame available (not really an error) -#define PM3_ENODATA -98 -// Quit program client: reserved, order to quit the program -#define PM3_EFATAL -99 - - -// LF -#define LF_FREQ2DIV(f) ((int)(((12000.0 + (f)/2.0)/(f))-1)) -#define LF_DIVISOR_125 LF_FREQ2DIV(125) -#define LF_DIVISOR_134 LF_FREQ2DIV(134.2) -#define LF_DIV2FREQ(d) (12000.0/((d)+1)) -#define LF_CMDREAD_MAX_EXTRA_SYMBOLS 4 - -// Receiving from USART need more than 30ms as we used on USB -// else we get errors about partial packet reception -// FTDI 9600 hw status -> we need 20ms -// FTDI 115200 hw status -> we need 50ms -// FTDI 460800 hw status -> we need 30ms -// BT 115200 hf mf fchk --1k -f file.dic -> we need 140ms -// all zero's configure: no timeout for read/write used. -// took settings from libnfc/buses/uart.c - -// uart_windows.c & uart_posix.c -# define UART_FPC_CLIENT_RX_TIMEOUT_MS 200 -# define UART_USB_CLIENT_RX_TIMEOUT_MS 20 -# define UART_TCP_CLIENT_RX_TIMEOUT_MS 500 - - -// CMD_DEVICE_INFO response packet has flags in arg[0], flag definitions: -/* Whether a bootloader that understands the g_common_area is present */ -#define DEVICE_INFO_FLAG_BOOTROM_PRESENT (1<<0) - -/* Whether a osimage that understands the g_common_area is present */ -#define DEVICE_INFO_FLAG_OSIMAGE_PRESENT (1<<1) - -/* Set if the bootloader is currently executing */ -#define DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM (1<<2) - -/* Set if the OS is currently executing */ -#define DEVICE_INFO_FLAG_CURRENT_MODE_OS (1<<3) - -/* Set if this device understands the extend start flash command */ -#define DEVICE_INFO_FLAG_UNDERSTANDS_START_FLASH (1<<4) - -/* Set if this device understands the chip info command */ -#define DEVICE_INFO_FLAG_UNDERSTANDS_CHIP_INFO (1<<5) - -/* Set if this device understands the version command */ -#define DEVICE_INFO_FLAG_UNDERSTANDS_VERSION (1<<6) - -#define BL_VERSION_MAJOR(version) ((uint32_t)(version) >> 22) -#define BL_VERSION_MINOR(version) (((uint32_t)(version) >> 12) & 0x3ff) -#define BL_VERSION_PATCH(version) ((uint32_t)(version) & 0xfff) -#define BL_MAKE_VERSION(major, minor, patch) (((major) << 22) | ((minor) << 12) | (patch)) -// Some boundaries to distinguish valid versions from corrupted info -#define BL_VERSION_FIRST_MAJOR 1 -#define BL_VERSION_LAST_MAJOR 99 -#define BL_VERSION_INVALID 0 -// Different versions here. Each version should increase the numbers -#define BL_VERSION_1_0_0 BL_MAKE_VERSION(1, 0, 0) - - -/* CMD_START_FLASH may have three arguments: start of area to flash, - end of area to flash, optional magic. - The bootrom will not allow to overwrite itself unless this magic - is given as third parameter */ - -#define START_FLASH_MAGIC 0x54494f44 // 'DOIT' - -#endif diff --git a/HardNestedSolver/pm3/uart/README.md b/HardNestedSolver/pm3/uart/README.md deleted file mode 100755 index 218e983..0000000 --- a/HardNestedSolver/pm3/uart/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# uart - -This contains functionality for talking to UART/Serial devices on different platforms. The official client will build either `uart_posix.c` and `uart_win32.c`. Build targets for these files are contained in `client/Makefile`. - -If you want to implement support for other platforms, you need to implement the methods provided in `uart.h`. - -## Implementing a new driver - -Each driver is called with a string, typically containing a path or other reference to a serial port on the host. The methods outlined in `uart.h` need to be implemented. - -The hardware uses `common/usb_cdc.c` to implement a USB CDC endpoint exposed by the Atmel MCU. - - diff --git a/HardNestedSolver/pm3/uart/uart.h b/HardNestedSolver/pm3/uart/uart.h deleted file mode 100755 index 3854b76..0000000 --- a/HardNestedSolver/pm3/uart/uart.h +++ /dev/null @@ -1,81 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// See LICENSE.txt for the text of the license. -//----------------------------------------------------------------------------- -// Generic uart / rs232/ serial port library -//----------------------------------------------------------------------------- - -#ifndef _UART_H_ -#define _UART_H_ - -#include "../common.h" - -/* serial_port is declared as a void*, which you should cast to whatever type - * makes sense to your connection method. Both the posix and win32 - * implementations define their own structs in place. - */ -typedef void *serial_port; - -/* Returned by uart_open if the serial port specified was invalid. - */ -#define INVALID_SERIAL_PORT (void*)(~1) - -/* Returned by uart_open if the serial port specified is in use by another - * process. - */ -#define CLAIMED_SERIAL_PORT (void*)(~2) - -/* Given a user-specified port name, connect to the port and return a structure - * used for future references to that port. - * - * On errors, this method returns INVALID_SERIAL_PORT or CLAIMED_SERIAL_PORT. - */ -serial_port uart_open(const char *pcPortName, uint32_t speed); - -/* Closes the given port. - */ -void uart_close(const serial_port sp); - -/* Reads from the given serial port for up to 30ms. - * pbtRx: A pointer to a buffer for the returned data to be written to. - * pszMaxRxLen: The maximum data size we want to be sent. - * pszRxLen: The number of bytes that we were actually sent. - * - * Returns TRUE if any data was fetched, even if it was less than pszMaxRxLen. - * - * Returns FALSE if there was an error reading from the device. Note that a - * partial read may have completed into the buffer by the corresponding - * implementation, so pszRxLen should be checked to see if any data was written. - */ -int uart_receive(const serial_port sp, uint8_t *pbtRx, uint32_t pszMaxRxLen, uint32_t *pszRxLen); - -/* Sends a buffer to a given serial port. - * pbtTx: A pointer to a buffer containing the data to send. - * len: The amount of data to be sent. - */ -int uart_send(const serial_port sp, const uint8_t *pbtTx, const uint32_t len); - -/* Sets the current speed of the serial port, in baud. - */ -bool uart_set_speed(serial_port sp, const uint32_t uiPortSpeed); - -/* Gets the current speed of the serial port, in baud. - */ -uint32_t uart_get_speed(const serial_port sp); - -/* Reconfigure timeouts - */ -int uart_reconfigure_timeouts(uint32_t value); -#endif // _UART_H_ - diff --git a/HardNestedSolver/pm3/uart/uart_posix.c b/HardNestedSolver/pm3/uart/uart_posix.c deleted file mode 100755 index 9dc9f80..0000000 --- a/HardNestedSolver/pm3/uart/uart_posix.c +++ /dev/null @@ -1,630 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// See LICENSE.txt for the text of the license. -//----------------------------------------------------------------------------- -// Generic uart / rs232/ serial port library -//----------------------------------------------------------------------------- - -// Test if we are dealing with posix operating systems -#ifndef _WIN32 -#define _DEFAULT_SOURCE - -#include "uart.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef HAVE_BLUEZ -#include -#include -#endif - -#include "../ui.h" - -// Taken from https://github.com/unbit/uwsgi/commit/b608eb1772641d525bfde268fe9d6d8d0d5efde7 -#ifndef SOL_TCP -# define SOL_TCP IPPROTO_TCP -#endif - -typedef struct termios term_info; -typedef struct { - int fd; // Serial port file descriptor - term_info tiOld; // Terminal info before using the port - term_info tiNew; // Terminal info during the transaction -} serial_port_unix_t_t; - -// see pm3_cmd.h -struct timeval timeout = { - .tv_sec = 0, // 0 second - .tv_usec = UART_FPC_CLIENT_RX_TIMEOUT_MS * 1000 -}; - -static uint32_t newtimeout_value = 0; -static bool newtimeout_pending = false; - -int uart_reconfigure_timeouts(uint32_t value) { - newtimeout_value = value; - newtimeout_pending = true; - return PM3_SUCCESS; -} - -serial_port uart_open(const char *pcPortName, uint32_t speed) { - serial_port_unix_t_t *sp = calloc(sizeof(serial_port_unix_t_t), sizeof(uint8_t)); - - if (sp == 0) { - PrintAndLogEx(ERR, "UART failed to allocate memory"); - return INVALID_SERIAL_PORT; - } - - // init timeouts - timeout.tv_usec = UART_FPC_CLIENT_RX_TIMEOUT_MS * 1000; - - char *prefix = strdup(pcPortName); - if (prefix == NULL) { - PrintAndLogEx(ERR, "error: string duplication"); - free(sp); - return INVALID_SERIAL_PORT; - } - str_lower(prefix); - - if (memcmp(prefix, "tcp:", 4) == 0) { - free(prefix); - - if (strlen(pcPortName) <= 4) { - free(sp); - return INVALID_SERIAL_PORT; - } - - struct addrinfo *addr = NULL, *rp; - - char *addrstr = strdup(pcPortName + 4); - if (addrstr == NULL) { - PrintAndLogEx(ERR, "error: string duplication"); - free(sp); - return INVALID_SERIAL_PORT; - } - - timeout.tv_usec = UART_TCP_CLIENT_RX_TIMEOUT_MS * 1000; - - char *colon = strrchr(addrstr, ':'); - const char *portstr; - if (colon) { - portstr = colon + 1; - *colon = '\0'; - } else { - portstr = "18888"; - } - - struct addrinfo info; - - memset(&info, 0, sizeof(info)); - - info.ai_socktype = SOCK_STREAM; - - int s = getaddrinfo(addrstr, portstr, &info, &addr); - if (s != 0) { - PrintAndLogEx(ERR, "error: getaddrinfo: %s", gai_strerror(s)); - freeaddrinfo(addr); - free(addrstr); - free(sp); - return INVALID_SERIAL_PORT; - } - - int sfd; - for (rp = addr; rp != NULL; rp = rp->ai_next) { - sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); - - if (sfd == -1) - continue; - - if (connect(sfd, rp->ai_addr, rp->ai_addrlen) != -1) - break; - - close(sfd); - } - - freeaddrinfo(addr); - free(addrstr); - - if (rp == NULL) { /* No address succeeded */ - PrintAndLogEx(ERR, "error: Could not connect"); - free(sp); - return INVALID_SERIAL_PORT; - } - - sp->fd = sfd; - - int one = 1; - int res = setsockopt(sp->fd, SOL_TCP, TCP_NODELAY, &one, sizeof(one)); - if (res != 0) { - free(sp); - return INVALID_SERIAL_PORT; - } - return sp; - } - - if (memcmp(prefix, "bt:", 3) == 0) { - free(prefix); - -#ifdef HAVE_BLUEZ - if (strlen(pcPortName) != 20) { - free(sp); - return INVALID_SERIAL_PORT; - } - - char *addrstr = strndup(pcPortName + 3, 17); - if (addrstr == NULL) { - PrintAndLogEx(ERR, "error: string duplication"); - free(sp); - return INVALID_SERIAL_PORT; - } - - struct sockaddr_rc addr = { 0 }; - addr.rc_family = AF_BLUETOOTH; - addr.rc_channel = (uint8_t) 1; - if (str2ba(addrstr, &addr.rc_bdaddr) != 0) { - PrintAndLogEx(ERR, "Invalid Bluetooth MAC address " _RED_("%s"), addrstr); - free(addrstr); - free(sp); - return INVALID_SERIAL_PORT; - } - int sfd = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); - if (sfd == -1) { - PrintAndLogEx(ERR, "Error opening Bluetooth socket"); - free(addrstr); - free(sp); - return INVALID_SERIAL_PORT; - } - if (connect(sfd, (struct sockaddr *)&addr, sizeof(addr)) == -1) { - PrintAndLogEx(ERR, "Error: cannot connect device " _YELLOW_("%s") " over Bluetooth", addrstr); - close(sfd); - free(addrstr); - free(sp); - return INVALID_SERIAL_PORT; - } - - sp->fd = sfd; - return sp; -#else // HAVE_BLUEZ - PrintAndLogEx(ERR, "Sorry, this client doesn't support native Bluetooth addresses"); - free(sp); - return INVALID_SERIAL_PORT; -#endif // HAVE_BLUEZ - } - // The socket for abstract namespace implement. - // Is local socket buffer, not a TCP or any net connection! - // so, you can't connect with address like: 127.0.0.1, or any IP - // see http://man7.org/linux/man-pages/man7/unix.7.html - if (memcmp(prefix, "socket:", 7) == 0) { - free(prefix); - - if (strlen(pcPortName) <= 7) { - free(sp); - return INVALID_SERIAL_PORT; - } - - // we must use max timeout! - timeout.tv_usec = UART_TCP_CLIENT_RX_TIMEOUT_MS * 1000; - - size_t servernameLen = (strlen(pcPortName) - 7) + 1; - char serverNameBuf[servernameLen]; - memset(serverNameBuf, '\0', servernameLen); - for (int i = 7, j = 0; j < servernameLen; ++i, ++j) { - serverNameBuf[j] = pcPortName[i]; - } - serverNameBuf[servernameLen - 1] = '\0'; - - int localsocket, len; - struct sockaddr_un remote; - - remote.sun_path[0] = '\0'; // abstract namespace - strcpy(remote.sun_path + 1, serverNameBuf); - remote.sun_family = AF_LOCAL; - int nameLen = strlen(serverNameBuf); - len = 1 + nameLen + offsetof(struct sockaddr_un, sun_path); - - if ((localsocket = socket(PF_LOCAL, SOCK_STREAM, 0)) == -1) { - free(sp); - return INVALID_SERIAL_PORT; - } - - if (connect(localsocket, (struct sockaddr *) &remote, len) == -1) { - close(localsocket); - free(sp); - return INVALID_SERIAL_PORT; - } - - sp->fd = localsocket; - return sp; - } - - free(prefix); - - sp->fd = open(pcPortName, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK); - if (sp->fd == -1) { - uart_close(sp); - return INVALID_SERIAL_PORT; - } - - // Finally figured out a way to claim a serial port interface under unix - // We just try to set a (advisory) lock on the file descriptor - struct flock fl; - fl.l_type = F_WRLCK; - fl.l_whence = SEEK_SET; - fl.l_start = 0; - fl.l_len = 0; - fl.l_pid = getpid(); - - // Does the system allows us to place a lock on this file descriptor - if (fcntl(sp->fd, F_SETLK, &fl) == -1) { - // A conflicting lock is held by another process - free(sp); - return CLAIMED_SERIAL_PORT; - } - - // Try to retrieve the old (current) terminal info struct - if (tcgetattr(sp->fd, &sp->tiOld) == -1) { - uart_close(sp); - return INVALID_SERIAL_PORT; - } - - // Duplicate the (old) terminal info struct - sp->tiNew = sp->tiOld; - - // Configure the serial port - sp->tiNew.c_cflag = CS8 | CLOCAL | CREAD; - sp->tiNew.c_iflag = IGNPAR; - sp->tiNew.c_oflag = 0; - sp->tiNew.c_lflag = 0; - - // Block until n bytes are received - sp->tiNew.c_cc[VMIN] = 0; - // Block until a timer expires (n * 100 mSec.) - sp->tiNew.c_cc[VTIME] = 0; - - // Try to set the new terminal info struct - if (tcsetattr(sp->fd, TCSANOW, &sp->tiNew) == -1) { - uart_close(sp); - return INVALID_SERIAL_PORT; - } - - // Flush all lingering data that may exist - tcflush(sp->fd, TCIOFLUSH); - - if (!uart_set_speed(sp, speed)) { - // try fallback automatically - speed = 115200; - if (!uart_set_speed(sp, speed)) { - uart_close(sp); - PrintAndLogEx(ERR, "UART error while setting baudrate"); - return INVALID_SERIAL_PORT; - } - } - - return sp; -} - -void uart_close(const serial_port sp) { - serial_port_unix_t_t *spu = (serial_port_unix_t_t *)sp; - tcflush(spu->fd, TCIOFLUSH); - tcsetattr(spu->fd, TCSANOW, &(spu->tiOld)); - struct flock fl; - fl.l_type = F_UNLCK; - fl.l_whence = SEEK_SET; - fl.l_start = 0; - fl.l_len = 0; - fl.l_pid = getpid(); - - // Does the system allows us to place a lock on this file descriptor - int err = fcntl(spu->fd, F_SETLK, &fl); - if (err == -1) { - //silent error message as it can be called from uart_open failing modes, e.g. when waiting for port to appear - //PrintAndLogEx(ERR, "UART error while closing port"); - } - close(spu->fd); - free(sp); -} - -int uart_receive(const serial_port sp, uint8_t *pbtRx, uint32_t pszMaxRxLen, uint32_t *pszRxLen) { - uint32_t byteCount; // FIONREAD returns size on 32b - fd_set rfds; - struct timeval tv; - - if (newtimeout_pending) { - timeout.tv_usec = newtimeout_value * 1000; - newtimeout_pending = false; - } - // Reset the output count - *pszRxLen = 0; - do { - // Reset file descriptor - FD_ZERO(&rfds); - FD_SET(((serial_port_unix_t_t *)sp)->fd, &rfds); - tv = timeout; - int res = select(((serial_port_unix_t_t *)sp)->fd + 1, &rfds, NULL, NULL, &tv); - - // Read error - if (res < 0) { - return PM3_EIO; - } - - // Read time-out - if (res == 0) { - if (*pszRxLen == 0) { - // We received no data - return PM3_ENODATA; - } else { - // We received some data, but nothing more is available - return PM3_SUCCESS; - } - } - - // Retrieve the count of the incoming bytes - res = ioctl(((serial_port_unix_t_t *)sp)->fd, FIONREAD, &byteCount); -// PrintAndLogEx(ERR, "UART:: RX ioctl res %d byteCount %u", res, byteCount); - if (res < 0) return PM3_ENOTTY; - - // Cap the number of bytes, so we don't overrun the buffer - if (pszMaxRxLen - (*pszRxLen) < byteCount) { -// PrintAndLogEx(ERR, "UART:: RX prevent overrun (have %u, need %u)", pszMaxRxLen - (*pszRxLen), byteCount); - byteCount = pszMaxRxLen - (*pszRxLen); - } - - // There is something available, read the data - res = read(((serial_port_unix_t_t *)sp)->fd, pbtRx + (*pszRxLen), byteCount); - - // Stop if the OS has some troubles reading the data - if (res <= 0) { - return PM3_EIO; - } - - *pszRxLen += res; - - if (*pszRxLen == pszMaxRxLen) { - // We have all the data we wanted. - return PM3_SUCCESS; - } - } while (byteCount); - - return PM3_SUCCESS; -} - -int uart_send(const serial_port sp, const uint8_t *pbtTx, const uint32_t len) { - uint32_t pos = 0; - fd_set rfds; - struct timeval tv; - - while (pos < len) { - // Reset file descriptor - FD_ZERO(&rfds); - FD_SET(((serial_port_unix_t_t *)sp)->fd, &rfds); - tv = timeout; - int res = select(((serial_port_unix_t_t *)sp)->fd + 1, NULL, &rfds, NULL, &tv); - - // Write error - if (res < 0) { - PrintAndLogEx(ERR, "UART:: write error (%d)", res); - return PM3_ENOTTY; - } - - // Write time-out - if (res == 0) { - PrintAndLogEx(ERR, "UART:: write time-out"); - return PM3_ETIMEOUT; - } - - // Send away the bytes - res = write(((serial_port_unix_t_t *)sp)->fd, pbtTx + pos, len - pos); - - // Stop if the OS has some troubles sending the data - if (res <= 0) - return PM3_EIO; - - pos += res; - } - return PM3_SUCCESS; -} - -bool uart_set_speed(serial_port sp, const uint32_t uiPortSpeed) { - const serial_port_unix_t_t *spu = (serial_port_unix_t_t *)sp; - speed_t stPortSpeed; - switch (uiPortSpeed) { - case 0: - stPortSpeed = B0; - break; - case 50: - stPortSpeed = B50; - break; - case 75: - stPortSpeed = B75; - break; - case 110: - stPortSpeed = B110; - break; - case 134: - stPortSpeed = B134; - break; - case 150: - stPortSpeed = B150; - break; - case 300: - stPortSpeed = B300; - break; - case 600: - stPortSpeed = B600; - break; - case 1200: - stPortSpeed = B1200; - break; - case 1800: - stPortSpeed = B1800; - break; - case 2400: - stPortSpeed = B2400; - break; - case 4800: - stPortSpeed = B4800; - break; - case 9600: - stPortSpeed = B9600; - break; - case 19200: - stPortSpeed = B19200; - break; - case 38400: - stPortSpeed = B38400; - break; -# ifdef B57600 - case 57600: - stPortSpeed = B57600; - break; -# endif -# ifdef B115200 - case 115200: - stPortSpeed = B115200; - break; -# endif -# ifdef B230400 - case 230400: - stPortSpeed = B230400; - break; -# endif -# ifdef B460800 - case 460800: - stPortSpeed = B460800; - break; -# endif -# ifdef B921600 - case 921600: - stPortSpeed = B921600; - break; -# endif -# ifdef B1382400 - case 1382400: - stPortSpeed = B1382400; - break; -# endif - - default: - return false; - }; - - struct termios ti; - if (tcgetattr(spu->fd, &ti) == -1) - return false; - - // Set port speed (Input and Output) - cfsetispeed(&ti, stPortSpeed); - cfsetospeed(&ti, stPortSpeed); - bool result = tcsetattr(spu->fd, TCSANOW, &ti) != -1; - - return result; -} - -uint32_t uart_get_speed(const serial_port sp) { - struct termios ti; - uint32_t uiPortSpeed; - const serial_port_unix_t_t *spu = (serial_port_unix_t_t *)sp; - - if (tcgetattr(spu->fd, &ti) == -1) - return 0; - - // Set port speed (Input) - speed_t stPortSpeed = cfgetispeed(&ti); - switch (stPortSpeed) { - case B0: - uiPortSpeed = 0; - break; - case B50: - uiPortSpeed = 50; - break; - case B75: - uiPortSpeed = 75; - break; - case B110: - uiPortSpeed = 110; - break; - case B134: - uiPortSpeed = 134; - break; - case B150: - uiPortSpeed = 150; - break; - case B300: - uiPortSpeed = 300; - break; - case B600: - uiPortSpeed = 600; - break; - case B1200: - uiPortSpeed = 1200; - break; - case B1800: - uiPortSpeed = 1800; - break; - case B2400: - uiPortSpeed = 2400; - break; - case B4800: - uiPortSpeed = 4800; - break; - case B9600: - uiPortSpeed = 9600; - break; - case B19200: - uiPortSpeed = 19200; - break; - case B38400: - uiPortSpeed = 38400; - break; -# ifdef B57600 - case B57600: - uiPortSpeed = 57600; - break; -# endif -# ifdef B115200 - case B115200: - uiPortSpeed = 115200; - break; -# endif -# ifdef B230400 - case B230400: - uiPortSpeed = 230400; - break; -# endif -# ifdef B460800 - case B460800: - uiPortSpeed = 460800; - break; -# endif -# ifdef B921600 - case B921600: - uiPortSpeed = 921600; - break; -# endif - default: - return 0; - }; - return uiPortSpeed; -} -#endif diff --git a/HardNestedSolver/pm3/uart/uart_win32.c b/HardNestedSolver/pm3/uart/uart_win32.c deleted file mode 100755 index 3f7cb22..0000000 --- a/HardNestedSolver/pm3/uart/uart_win32.c +++ /dev/null @@ -1,411 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// See LICENSE.txt for the text of the license. -//----------------------------------------------------------------------------- -// Generic uart / rs232/ serial port library -//----------------------------------------------------------------------------- - -#include "uart.h" - -#include -#include -#include -#include "../ui.h" - -// The windows serial port implementation -#ifdef _WIN32 -#define WIN32_LEAN_AND_MEAN -#include -#include -#include - -typedef struct { - HANDLE hPort; // Serial port handle - DCB dcb; // Device control settings - COMMTIMEOUTS ct; // Serial port time-out configuration - SOCKET hSocket; // Socket handle -} serial_port_windows_t; - -// this is for TCP connection -struct timeval timeout = { - .tv_sec = 0, // 0 second - .tv_usec = UART_TCP_CLIENT_RX_TIMEOUT_MS * 1000 -}; - -uint32_t newtimeout_value = 0; -bool newtimeout_pending = false; - -int uart_reconfigure_timeouts(uint32_t value) { - newtimeout_value = value; - newtimeout_pending = true; - return PM3_SUCCESS; -} - -static int uart_reconfigure_timeouts_polling(serial_port sp) { - if (newtimeout_pending == false) - return PM3_SUCCESS; - newtimeout_pending = false; - - serial_port_windows_t *spw; - spw = (serial_port_windows_t *)sp; - spw->ct.ReadIntervalTimeout = newtimeout_value; - spw->ct.ReadTotalTimeoutMultiplier = 0; - spw->ct.ReadTotalTimeoutConstant = newtimeout_value; - spw->ct.WriteTotalTimeoutMultiplier = newtimeout_value; - spw->ct.WriteTotalTimeoutConstant = 0; - - if (!SetCommTimeouts(spw->hPort, &spw->ct)) { - uart_close(spw); - return PM3_EIO; - } - - PurgeComm(spw->hPort, PURGE_RXABORT | PURGE_RXCLEAR); - return PM3_SUCCESS; -} - -serial_port uart_open(const char *pcPortName, uint32_t speed) { - char acPortName[255] = {0}; - serial_port_windows_t *sp = calloc(sizeof(serial_port_windows_t), sizeof(uint8_t)); - sp->hSocket = INVALID_SOCKET; // default: serial port - - if (sp == 0) { - PrintAndLogEx(WARNING, "UART failed to allocate memory\n"); - return INVALID_SERIAL_PORT; - } - - char *prefix = strdup(pcPortName); - if (prefix == NULL) { - PrintAndLogEx(ERR, "error: string duplication"); - free(sp); - return INVALID_SERIAL_PORT; - } - str_lower(prefix); - - if (memcmp(prefix, "tcp:", 4) == 0) { - free(prefix); - - if (strlen(pcPortName) <= 4) { - free(sp); - return INVALID_SERIAL_PORT; - } - - struct addrinfo *addr = NULL, *rp; - - char *addrstr = strdup(pcPortName + 4); - if (addrstr == NULL) { - PrintAndLogEx(ERR, "error: string duplication"); - free(sp); - return INVALID_SERIAL_PORT; - } - - timeout.tv_usec = UART_TCP_CLIENT_RX_TIMEOUT_MS * 1000; - - char *colon = strrchr(addrstr, ':'); - const char *portstr; - if (colon) { - portstr = colon + 1; - *colon = '\0'; - } else { - portstr = "18888"; - } - - WSADATA wsaData; - struct addrinfo info; - int iResult; - - iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); - if (iResult != 0) { - PrintAndLogEx(ERR, "error: WSAStartup failed with error: %d", iResult); - free(sp); - return INVALID_SERIAL_PORT; - } - - memset(&info, 0, sizeof(info)); - info.ai_socktype = SOCK_STREAM; - info.ai_protocol = IPPROTO_TCP; - - int s = getaddrinfo(addrstr, portstr, &info, &addr); - if (s != 0) { - PrintAndLogEx(ERR, "error: getaddrinfo: %s", gai_strerror(s)); - freeaddrinfo(addr); - free(addrstr); - free(sp); - WSACleanup(); - return INVALID_SERIAL_PORT; - } - - SOCKET hSocket = INVALID_SOCKET; - for (rp = addr; rp != NULL; rp = rp->ai_next) { - hSocket = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); - - if (hSocket == INVALID_SOCKET) - continue; - - if (connect(hSocket, rp->ai_addr, (int)rp->ai_addrlen) != INVALID_SOCKET) - break; - - closesocket(hSocket); - hSocket = INVALID_SOCKET; - } - - freeaddrinfo(addr); - free(addrstr); - - if (rp == NULL) { /* No address succeeded */ - PrintAndLogEx(ERR, "error: Could not connect"); - WSACleanup(); - free(sp); - return INVALID_SERIAL_PORT; - } - - sp->hSocket = hSocket; - - int one = 1; - int res = setsockopt(sp->hSocket, IPPROTO_TCP, TCP_NODELAY, (char *)&one, sizeof(one)); - if (res != 0) { - closesocket(hSocket); - WSACleanup(); - free(sp); - return INVALID_SERIAL_PORT; - } - return sp; - } - - // Copy the input "com?" to "\\.\COM?" format - snprintf(acPortName, sizeof(acPortName), "\\\\.\\%s", pcPortName); - _strupr(acPortName); - - // Try to open the serial port - // r/w, none-share comport, no security, existing, no overlapping, no templates - sp->hPort = CreateFileA(acPortName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); - if (sp->hPort == INVALID_HANDLE_VALUE) { - uart_close(sp); - return INVALID_SERIAL_PORT; - } - - // Prepare the device control - // doesn't matter since PM3 device ignores this CDC command: set_line_coding in usb_cdc.c - memset(&sp->dcb, 0, sizeof(DCB)); - sp->dcb.DCBlength = sizeof(DCB); - if (!BuildCommDCBA("baud=115200 parity=N data=8 stop=1", &sp->dcb)) { - uart_close(sp); - PrintAndLogEx(WARNING, "UART error cdc setup\n"); - return INVALID_SERIAL_PORT; - } - - // Update the active serial port - if (!SetCommState(sp->hPort, &sp->dcb)) { - uart_close(sp); - PrintAndLogEx(WARNING, "UART error while setting com state\n"); - return INVALID_SERIAL_PORT; - } - - uart_reconfigure_timeouts(UART_FPC_CLIENT_RX_TIMEOUT_MS); - uart_reconfigure_timeouts_polling(sp); - - if (!uart_set_speed(sp, speed)) { - // try fallback automatically - speed = 115200; - if (!uart_set_speed(sp, speed)) { - uart_close(sp); - PrintAndLogEx(WARNING, "UART error while setting baudrate\n"); - return INVALID_SERIAL_PORT; - } - } - - return sp; -} - -void uart_close(const serial_port sp) { - serial_port_windows_t *spw = (serial_port_windows_t *)sp; - if (spw->hSocket != INVALID_SOCKET) { - shutdown(spw->hSocket, SD_BOTH); - closesocket(spw->hSocket); - WSACleanup(); - } - if (spw->hPort != INVALID_HANDLE_VALUE) - CloseHandle(spw->hPort); - free(sp); -} - -bool uart_set_speed(serial_port sp, const uint32_t uiPortSpeed) { - serial_port_windows_t *spw; - - // Set port speed (Input and Output) - switch (uiPortSpeed) { - case 9600: - case 19200: - case 38400: - case 57600: - case 115200: - case 230400: - case 460800: - case 921600: - case 1382400: - break; - default: - return false; - }; - - spw = (serial_port_windows_t *)sp; - spw->dcb.BaudRate = uiPortSpeed; - bool result = SetCommState(spw->hPort, &spw->dcb); - PurgeComm(spw->hPort, PURGE_RXABORT | PURGE_RXCLEAR); - - return result; -} - -uint32_t uart_get_speed(const serial_port sp) { - const serial_port_windows_t *spw = (serial_port_windows_t *)sp; - if (!GetCommState(spw->hPort, (serial_port) & spw->dcb)) - return spw->dcb.BaudRate; - - return 0; -} - -int uart_receive(const serial_port sp, uint8_t *pbtRx, uint32_t pszMaxRxLen, uint32_t *pszRxLen) { - serial_port_windows_t *spw = (serial_port_windows_t *)sp; - if (spw->hSocket == INVALID_SOCKET) { // serial port - uart_reconfigure_timeouts_polling(sp); - - int res = ReadFile(((serial_port_windows_t *)sp)->hPort, pbtRx, pszMaxRxLen, (LPDWORD)pszRxLen, NULL); - if (res) - return PM3_SUCCESS; - - int errorcode = GetLastError(); - - if (res == 0 && errorcode == 2) { - return PM3_EIO; - } - - return PM3_ENOTTY; - } else { // TCP - uint32_t byteCount; // FIONREAD returns size on 32b - fd_set rfds; - struct timeval tv; - - if (newtimeout_pending) { - timeout.tv_usec = newtimeout_value * 1000; - newtimeout_pending = false; - } - // Reset the output count - *pszRxLen = 0; - do { - // Reset file descriptor - FD_ZERO(&rfds); - FD_SET(spw->hSocket, &rfds); - tv = timeout; - // the first argument nfds is ignored in Windows - int res = select(0, &rfds, NULL, NULL, &tv); - - // Read error - if (res == SOCKET_ERROR) { - return PM3_EIO; - } - - // Read time-out - if (res == 0) { - if (*pszRxLen == 0) { - // We received no data - return PM3_ENODATA; - } else { - // We received some data, but nothing more is available - return PM3_SUCCESS; - } - } - - // Retrieve the count of the incoming bytes - res = ioctlsocket(spw->hSocket, FIONREAD, (u_long *)&byteCount); - // PrintAndLogEx(ERR, "UART:: RX ioctl res %d byteCount %u", res, byteCount); - if (res == SOCKET_ERROR) return PM3_ENOTTY; - - // Cap the number of bytes, so we don't overrun the buffer - if (pszMaxRxLen - (*pszRxLen) < byteCount) { - // PrintAndLogEx(ERR, "UART:: RX prevent overrun (have %u, need %u)", pszMaxRxLen - (*pszRxLen), byteCount); - byteCount = pszMaxRxLen - (*pszRxLen); - } - - // There is something available, read the data - res = recv(spw->hSocket, (char *)pbtRx + (*pszRxLen), byteCount, 0); - - // Stop if the OS has some troubles reading the data - if (res <= 0) { // includes 0(gracefully closed) and -1(SOCKET_ERROR) - return PM3_EIO; - } - - *pszRxLen += res; - - if (*pszRxLen == pszMaxRxLen) { - // We have all the data we wanted. - return PM3_SUCCESS; - } - } while (byteCount); - - return PM3_SUCCESS; - } -} - -int uart_send(const serial_port sp, const uint8_t *p_tx, const uint32_t len) { - serial_port_windows_t *spw = (serial_port_windows_t *)sp; - if (spw->hSocket == INVALID_SOCKET) { // serial port - DWORD txlen = 0; - int res = WriteFile(((serial_port_windows_t *)sp)->hPort, p_tx, len, &txlen, NULL); - if (res) - return PM3_SUCCESS; - - int errorcode = GetLastError(); - if (res == 0 && errorcode == 2) { - return PM3_EIO; - } - return PM3_ENOTTY; - } else { // TCP - uint32_t pos = 0; - fd_set wfds; - struct timeval tv; - - while (pos < len) { - // Reset file descriptor - FD_ZERO(&wfds); - FD_SET(spw->hSocket, &wfds); - tv = timeout; - // the first argument nfds is ignored in Windows - int res = select(0, NULL, &wfds, NULL, &tv); - - // Write error - if (res == SOCKET_ERROR) { - PrintAndLogEx(ERR, "UART:: write error (%d)", res); - return PM3_ENOTTY; - } - - // Write time-out - if (res == 0) { - PrintAndLogEx(ERR, "UART:: write time-out"); - return PM3_ETIMEOUT; - } - - // Send away the bytes - res = send(spw->hSocket, (const char *)p_tx + pos, len - pos, 0); - - // Stop if the OS has some troubles sending the data - if (res <= 0) - return PM3_EIO; - - pos += res; - } - return PM3_SUCCESS; - - } -} - -#endif diff --git a/HardNestedSolver/pm3/ui.c b/HardNestedSolver/pm3/ui.c index 1b9b9c3..761eedf 100755 --- a/HardNestedSolver/pm3/ui.c +++ b/HardNestedSolver/pm3/ui.c @@ -18,9 +18,6 @@ /* Ensure strtok_r is available even with -std=c99; must be included before */ -#if !defined(_WIN32) -#define _POSIX_C_SOURCE 200112L -#endif #include "ui.h" #include "commonutil.h" // ARRAYLEN @@ -33,32 +30,19 @@ #include #endif -#include #include "util.h" -#define PROXLOG "log_%Y%m%d.txt" -#include "fileutils.h" -#include "pm3_cmd.h" #ifdef _WIN32 # include // _mkdir #endif -#include #include "emojis.h" #include "emojis_alt.h" +#include session_arg_t g_session; -double g_CursorScaleFactor = 1; -char g_CursorScaleFactorUnit[11] = {0}; -double g_PlotGridX = 0, g_PlotGridY = 0, g_PlotGridXdefault = 64, g_PlotGridYdefault = 64; -uint32_t g_CursorCPos = 0, g_CursorDPos = 0, g_GraphStop = 0; -uint32_t g_GraphStart = 0; // Starting point/offset for the left side of the graph -double g_GraphPixelsPerPoint = 1.f; // How many visual pixels are between each sample point (x axis) static bool flushAfterWrite = false; -double g_GridOffset = 0; -bool g_GridLocked = false; - static void fPrintAndLog(FILE *stream, const char *fmt, ...); #ifdef _WIN32 @@ -69,127 +53,6 @@ static void fPrintAndLog(FILE *stream, const char *fmt, ...); #define STRTOK strtok_r #endif - -// needed by flasher, so let's put it here instead of fileutils.c -int searchHomeFilePath(char **foundpath, const char *subdir, const char *filename, bool create_home) { - if (foundpath == NULL) { - return PM3_EINVARG; - } - - const char *user_path = NULL; - if (user_path == NULL) { - return PM3_EFILE; - } - - size_t pathlen = strlen(user_path) + strlen(PM3_USER_DIRECTORY) + 1; - char *path = calloc(pathlen, sizeof(char)); - if (path == NULL) { - return PM3_EMALLOC; - } - - strcpy(path, user_path); - strcat(path, PM3_USER_DIRECTORY); - int result; - -#ifdef _WIN32 - struct _stat st; - // Mingw _stat fails if path ends with /, so let's use a stripped path - if (str_endswith(path, PATHSEP)) { - memset(path + (strlen(path) - strlen(PATHSEP)), 0x00, strlen(PATHSEP)); - result = _stat(path, &st); - strcat(path, PATHSEP); - } else { - result = _stat(path, &st); - } -#else - struct stat st; - result = stat(path, &st); -#endif - - if ((result != 0) && create_home) { - - if (MKDIR_CHK) { - fprintf(stderr, "Could not create user directory %s\n", path); - free(path); - return PM3_EFILE; - } - } - - if (subdir != NULL) { - pathlen += strlen(subdir); - char *tmp = realloc(path, pathlen * sizeof(char)); - if (tmp == NULL) { - //free(path); - return PM3_EMALLOC; - } - path = tmp; - strcat(path, subdir); - -#ifdef _WIN32 - // Mingw _stat fails if path ends with /, so let's use a stripped path - if (str_endswith(path, PATHSEP)) { - memset(path + (strlen(path) - strlen(PATHSEP)), 0x00, strlen(PATHSEP)); - result = _stat(path, &st); - strcat(path, PATHSEP); - } else { - result = _stat(path, &st); - } -#else - result = stat(path, &st); -#endif - - if ((result != 0) && create_home) { - - if (MKDIR_CHK) { - fprintf(stderr, "Could not create user directory %s\n", path); - free(path); - return PM3_EFILE; - } - } - } - - if (filename == NULL) { - *foundpath = path; - return PM3_SUCCESS; - } - - pathlen += strlen(filename); - char *tmp = realloc(path, pathlen * sizeof(char)); - if (tmp == NULL) { - //free(path); - return PM3_EMALLOC; - } - - path = tmp; - strcat(path, filename); - *foundpath = path; - - return PM3_SUCCESS; -} - -void PrintAndLogOptions(const char *str[][2], size_t size, size_t space) { - char buff[2000] = "Options:\n"; - char format[2000] = ""; - size_t counts[2] = {0, 0}; - for (size_t i = 0; i < size; i++) - for (size_t j = 0; j < 2; j++) - if (counts[j] < strlen(str[i][j])) { - counts[j] = strlen(str[i][j]); - } - for (size_t i = 0; i < size; i++) { - for (size_t j = 0; j < 2; j++) { - if (j == 0) - snprintf(format, sizeof(format), "%%%zus%%%zus", space, counts[j]); - else - snprintf(format, sizeof(format), "%%%zus%%-%zus", space, counts[j]); - snprintf(buff + strlen(buff), sizeof(buff) - strlen(buff), format, " ", str[i][j]); - } - if (i < size - 1) - strncat(buff, "\n", sizeof(buff) - strlen(buff) - 1); - } - PrintAndLogEx(NORMAL, "%s", buff); -} - static uint8_t PrintAndLogEx_spinidx = 0; void PrintAndLogEx(logLevel_t level, const char *fmt, ...) { @@ -320,54 +183,25 @@ static void fPrintAndLog(FILE *stream, const char *fmt, ...) { // lock this section to avoid interlacing prints from different threads bool linefeed = true; - if (logging && g_session.incognito) { - logging = 0; - } - if ((g_printAndLog & PRINTANDLOG_LOG) && logging && !logfile) { - char *my_logfile_path = NULL; - char filename[40]; - struct tm *timenow; - time_t now = time(NULL); - timenow = gmtime(&now); - strftime(filename, sizeof(filename), PROXLOG, timenow); - if (searchHomeFilePath(&my_logfile_path, LOGS_SUBDIR, filename, true) != PM3_SUCCESS) { - my_logfile_path = NULL; - logging = 0; - } else { - logfile = fopen(my_logfile_path, "a"); - if (logfile == NULL) { - printf(_YELLOW_("[-]") " Can't open logfile %s, logging disabled!\n", my_logfile_path); - logging = 0; - } else { - - if (g_session.supports_colors) { - printf("["_YELLOW_("=")"] Session log " _YELLOW_("%s") "\n", my_logfile_path); - } else { - printf("[=] Session log %s\n", my_logfile_path); - } - - } - free(my_logfile_path); - } - } + logging = 0; // If there is an incoming message from the hardware (eg: lf hid read) in // the background (while the prompt is displayed and accepting user input), // stash the prompt and bring it back later. #ifdef RL_STATE_READCMD - // We are using GNU readline. libedit (OSX) doesn't support this flag. - int need_hack = (rl_readline_state & RL_STATE_READCMD) > 0; - char *saved_line; - int saved_point; - - if (need_hack) { - saved_point = rl_point; - saved_line = rl_copy_text(0, rl_end); - rl_save_prompt(); - rl_replace_line("", 0); - rl_redisplay(); - } + // We are using GNU readline. libedit (OSX) doesn't support this flag. + int need_hack = (rl_readline_state & RL_STATE_READCMD) > 0; + char *saved_line; + int saved_point; + + if (need_hack) { + saved_point = rl_point; + saved_line = rl_copy_text(0, rl_end); + rl_save_prompt(); + rl_replace_line("", 0); + rl_redisplay(); + } #endif va_start(argptr, fmt); @@ -414,26 +248,6 @@ static void fPrintAndLog(FILE *stream, const char *fmt, ...) { fflush(stdout); } -void SetFlushAfterWrite(bool value) { - flushAfterWrite = value; -} - -bool GetFlushAfterWrite(void) { - return flushAfterWrite; -} - -void memcpy_filter_rlmarkers(void *dest, const void *src, size_t n) { - uint8_t *rdest = (uint8_t *) dest; - uint8_t *rsrc = (uint8_t *) src; - uint16_t si = 0; - for (size_t i = 0; i < n; i++) { - if ((rsrc[i] == '\001') || (rsrc[i] == '\002')) - // skip readline special markers - continue; - rdest[si++] = rsrc[i]; - } -} - void memcpy_filter_ansi(void *dest, const void *src, size_t n, bool filter) { if (filter) { // Filter out ANSI sequences on these OS @@ -571,164 +385,4 @@ void memcpy_filter_emoji(void *dest, const void *src, size_t n, emojiMode_t mode memcpy(rdest + si, current_token, current_token_length); } } -} - -/* -// If reactivated, beware it doesn't compile on Android (DXL) -void iceIIR_Butterworth(int *data, const size_t len) { - - int *output = (int *) calloc(sizeof(int) * len, sizeof(uint8_t)); - if (!output) return; - - // clear mem - memset(output, 0x00, len); - - size_t adjustedLen = len; - float fc = 0.1125f; // center frequency - - // create very simple low-pass filter to remove images (2nd-order Butterworth) - float complex iir_buf[3] = {0, 0, 0}; - float b[3] = {0.003621681514929, 0.007243363029857, 0.003621681514929}; - float a[3] = {1.000000000000000, -1.822694925196308, 0.837181651256023}; - - for (size_t i = 0; i < adjustedLen; ++i) { - - float sample = data[i]; // input sample read from array - float complex x_prime = 1.0f; // save sample for estimating frequency - float complex x; - - // remove DC offset and mix to complex baseband - x = (sample - 127.5f) * cexpf(_Complex_I * 2 * M_PI * fc * i); - - // apply low-pass filter, removing spectral image (IIR using direct-form II) - iir_buf[2] = iir_buf[1]; - iir_buf[1] = iir_buf[0]; - iir_buf[0] = x - a[1] * iir_buf[1] - a[2] * iir_buf[2]; - x = b[0] * iir_buf[0] + - b[1] * iir_buf[1] + - b[2] * iir_buf[2]; - - // compute instantaneous frequency by looking at phase difference - // between adjacent samples - float freq = cargf(x * conjf(x_prime)); - x_prime = x; // retain this sample for next iteration - - output[i] = (freq > 0) ? 127 : -127; - } - - // show data - //memcpy(data, output, adjustedLen); - for (size_t j = 0; j < adjustedLen; ++j) - data[j] = output[j]; - - free(output); -} -*/ - -void iceSimple_Filter(int *data, const size_t len, uint8_t k) { -// ref: http://www.edn.com/design/systems-design/4320010/A-simple-software-lowpass-filter-suits-embedded-system-applications -// parameter K -#define FILTER_SHIFT 4 - - int32_t filter_reg = 0; - int8_t shift = (k <= 8) ? k : FILTER_SHIFT; - - for (size_t i = 0; i < len; ++i) { - // Update filter with current sample - filter_reg = filter_reg - (filter_reg >> shift) + data[i]; - - // Scale output for unity gain - data[i] = filter_reg >> shift; - } -} - -void print_progress(size_t count, uint64_t max, barMode_t style) { - int cols = 100 + 35; -#if defined(HAVE_READLINE) - static int prev_cols = 0; - int rows; - rl_reset_screen_size(); // refresh Readline idea of the actual screen width - rl_get_screen_size(&rows, &cols); - - if (cols < 36) - return; - - (void) rows; - if (prev_cols > cols) { - PrintAndLogEx(NORMAL, _CLEAR_ _TOP_ ""); - } - prev_cols = cols; -#endif - int width = cols - 35; - -#define PERCENTAGE(V, T) ((V * width) / T) - // x/8 fractional part of the percentage -#define PERCENTAGEFRAC(V, T) ((uint8_t)(((((float)V * width) / T) - ((V * width) / T)) * 8)) - - const char *smoothtable[] = {"\xe2\x80\x80", "\xe2\x96\x8F", "\xe2\x96\x8E", "\xe2\x96\x8D", "\xe2\x96\x8C", - "\xe2\x96\x8B", "\xe2\x96\x8A", "\xe2\x96\x89", "\xe2\x96\x88",}; - - int mode = (g_session.emoji_mode == EMO_EMOJI); - - const char *block[] = {"#", "\xe2\x96\x88"}; - // use a 3-byte space in emoji mode to ease computations - const char *space[] = {" ", "\xe2\x80\x80"}; - - size_t unit = strlen(block[mode]); - // +1 for \0 - char *bar = (char *) calloc(unit * width + 1, sizeof(uint8_t)); - - uint8_t value = PERCENTAGE(count, max); - - int i = 0; - // prefix is added already. - for (; i < unit * value; i += unit) { - memcpy(bar + i, block[mode], unit); - } - // add last block - if (mode == 1) { - memcpy(bar + i, smoothtable[PERCENTAGEFRAC(count, max)], unit); - } else { - memcpy(bar + i, space[mode], unit); - } - i += unit; - // add spaces - for (; i < unit * width; i += unit) { - memcpy(bar + i, space[mode], unit); - } - // color buffer - size_t collen = strlen(bar) + 40; - char *cbar = (char *) calloc(collen, sizeof(uint8_t)); - - // Add colors - if (g_session.supports_colors) { - int p60 = unit * (width * 60 / 100); - int p20 = unit * (width * 20 / 100); - snprintf(cbar, collen, _GREEN_("%.*s"), p60, bar); - snprintf(cbar + strlen(cbar), collen - strlen(cbar), _CYAN_("%.*s"), p20, bar + p60); - snprintf(cbar + strlen(cbar), collen - strlen(cbar), _YELLOW_("%.*s"), (int) (unit * width - p60 - p20), - bar + p60 + p20); - } else { - snprintf(cbar, collen, "%s", bar); - } - - switch (style) { - case STYLE_BAR: { - printf("\b%c[2K\r[" _YELLOW_("=")"] %s", 27, cbar); - break; - } - case STYLE_MIXED: { - printf("\b%c[2K\r[" _YELLOW_("=")"] %s [ %zu mV / %2u V / %2u Vmax ]", 27, cbar, count, - (uint32_t) (count / 1000), (uint32_t) (max / 1000)); - break; - } - case STYLE_VALUE: { - printf("[" _YELLOW_("=")"] %zu mV / %2u V / %2u Vmax \r", count, (uint32_t) (count / 1000), - (uint32_t) (max / 1000)); - break; - } - } - fflush(stdout); - free(bar); - free(cbar); -} +} \ No newline at end of file diff --git a/HardNestedSolver/pm3/ui.h b/HardNestedSolver/pm3/ui.h index f69afdc..09e1cc0 100755 --- a/HardNestedSolver/pm3/ui.h +++ b/HardNestedSolver/pm3/ui.h @@ -67,21 +67,10 @@ extern session_arg_t g_session; #endif #define MAX_PRINT_BUFFER 2048 -#define PROMPT_CLEARLINE PrintAndLogEx(INPLACE, " \r") -void PrintAndLogOptions(const char *str[][2], size_t size, size_t space); void PrintAndLogEx(logLevel_t level, const char *fmt, ...); -void SetFlushAfterWrite(bool value); -bool GetFlushAfterWrite(void); void memcpy_filter_ansi(void *dest, const void *src, size_t n, bool filter); -void memcpy_filter_rlmarkers(void *dest, const void *src, size_t n); void memcpy_filter_emoji(void *dest, const void *src, size_t n, emojiMode_t mode); -int searchHomeFilePath(char **foundpath, const char *subdir, const char *filename, bool create_home); - -void print_progress(size_t count, uint64_t max, barMode_t style); - -void iceIIR_Butterworth(int *data, const size_t len); -void iceSimple_Filter(int *data, const size_t len, uint8_t k); #ifdef __cplusplus } #endif diff --git a/HardNestedSolver/pm3/util.c b/HardNestedSolver/pm3/util.c index 51408a5..d37c7d3 100755 --- a/HardNestedSolver/pm3/util.c +++ b/HardNestedSolver/pm3/util.c @@ -16,1067 +16,20 @@ // utilities //----------------------------------------------------------------------------- -// ensure gmtime_r is available even with -std=c99; must be included before -#if !defined(_WIN32) && !defined(__APPLE__) -#define _POSIX_C_SOURCE 200112L -#endif - #include "util.h" -#include -#include -#include -#include -#include -#include -#include // Mingw - -#include "ui.h" // PrintAndLog - -#define UTIL_BUFFER_SIZE_SPRINT 8196 // global client debug variable uint8_t g_debugMode = 0; // global client disable logging variable uint8_t g_printAndLog = PRINTANDLOG_PRINT | PRINTANDLOG_LOG; // global client tell if a pending prompt is present -bool g_pendingPrompt = false; #ifdef _WIN32 #include -#endif - -#define MAX_BIN_BREAK_LENGTH (3072 + 384 + 1) - -#ifndef _WIN32 -#include -#include - -int kbd_enter_pressed(void) { - int flags; - if ((flags = fcntl(STDIN_FILENO, F_GETFL, 0)) < 0) { - PrintAndLogEx(ERR, "fcntl failed in kbd_enter_pressed"); - return -1; - } - //non-blocking - flags |= O_NONBLOCK; - if (fcntl(STDIN_FILENO, F_SETFL, flags) < 0) { - PrintAndLogEx(ERR, "fcntl failed in kbd_enter_pressed"); - return -1; - } - int c; - int ret = 0; - do { //get all available chars - c = getchar(); - ret |= c == '\n'; - } while (c != EOF); - //blocking - flags &= ~O_NONBLOCK; - if (fcntl(STDIN_FILENO, F_SETFL, flags) < 0) { - PrintAndLogEx(ERR, "fcntl failed in kbd_enter_pressed"); - return -1; - } - return ret; -} - #else - -#include -int kbd_enter_pressed(void) { - int ret = 0; - while (kbhit()) { - ret |= getch() == '\r'; - } - return ret; -} +#include #endif -static char b2s(uint8_t v, bool uppercase) { - // clear higher bits - v &= 0xF; - - switch (v) { - case 0xA : - return (uppercase ? 'A' : 'a') ; - case 0xB : - return (uppercase ? 'B' : 'b') ; - case 0xC : - return (uppercase ? 'C' : 'c') ; - case 0xD : - return (uppercase ? 'D' : 'd') ; - case 0xE : - return (uppercase ? 'E' : 'e') ; - case 0xF : - return (uppercase ? 'F' : 'f') ; - default: - return (char)(v + 0x30); - } -} - -// create filename on hex uid. -// param *fn - pointer to filename char array -// param *uid - pointer to uid byte array -// param *ext - ".log" -// param uidlen - length of uid array. -void FillFileNameByUID(char *filenamePrefix, const uint8_t *uid, const char *ext, const int uidlen) { - if (filenamePrefix == NULL || uid == NULL || ext == NULL) { - return; - } - - int len = strlen(filenamePrefix); - - for (int j = 0; j < uidlen; j++) { - // This is technically not the safest option, but there is no way to make this work without changing the function signature - // Possibly todo for future PR, but given UID lenghts are defined by program and not variable, should not be an issue - snprintf(filenamePrefix + len + j * 2, 3, "%02X", uid[j]); - } - - strcat(filenamePrefix, ext); -} - -// fill buffer from structure [{uint8_t data, size_t length},...] -int FillBuffer(uint8_t *data, size_t maxDataLength, size_t *dataLength, ...) { - *dataLength = 0; - va_list valist; - va_start(valist, dataLength); - - uint8_t *vdata = NULL; - - do { - vdata = va_arg(valist, uint8_t *); - if (!vdata) - break; - - size_t vlength = va_arg(valist, size_t); - if (*dataLength + vlength > maxDataLength) { - va_end(valist); - return 1; - } - - memcpy(&data[*dataLength], vdata, vlength); - *dataLength += vlength; - - } while (vdata); - - va_end(valist); - - return 0; -} - -bool CheckStringIsHEXValue(const char *value) { - for (size_t i = 0; i < strlen(value); i++) - if (!isxdigit(value[i])) - return false; - - if (strlen(value) % 2) - return false; - - return true; -} - -void ascii_to_buffer(uint8_t *buf, const uint8_t *hex_data, const size_t hex_len, - const size_t hex_max_len, const size_t min_str_len) { - - if (buf == NULL) return; - - char *tmp_base = (char *)buf; - char *tmp = tmp_base; - - size_t max_len = (hex_len > hex_max_len) ? hex_max_len : hex_len; - - size_t i = 0; - for (i = 0; i < max_len; ++i, tmp++) { - char c = hex_data[i]; - *tmp = ((c < 32) || (c == 127)) ? '.' : c; - } - - size_t m = (min_str_len > i) ? min_str_len : 0; - if (m > hex_max_len) - m = hex_max_len; - - for (; i < m; i++, tmp++) - *tmp = ' '; - - // remove last space - *tmp = '\0'; -} - -void hex_to_buffer(uint8_t *buf, const uint8_t *hex_data, const size_t hex_len, const size_t hex_max_len, - const size_t min_str_len, const size_t spaces_between, bool uppercase) { - - // sanity check - if (buf == NULL || hex_len < 1) - return; - - // 1. hex string length. - // 2. byte array to be converted to string - // - - size_t max_byte_len = (hex_len > hex_max_len) ? hex_max_len : hex_len; - size_t max_str_len = (max_byte_len * (2 + spaces_between)) + 1; - char *tmp_base = (char *)buf; - char *tmp = tmp_base; - - size_t i; - for (i = 0; (i < max_byte_len) && (max_str_len > strlen(tmp_base)) ; ++i) { - - *(tmp++) = b2s((hex_data[i] >> 4), uppercase); - *(tmp++) = b2s(hex_data[i], uppercase); - - for (size_t j = 0; j < spaces_between; j++) - *(tmp++) = ' '; - } - - i *= (2 + spaces_between); - - size_t m = (min_str_len > i) ? min_str_len : 0; - if (m > hex_max_len) - m = hex_max_len; - - while (m--) - *(tmp++) = ' '; - - // remove last space - *tmp = '\0'; - -} - -// printing and converting functions -void print_hex(const uint8_t *data, const size_t len) { - if (data == NULL || len == 0) return; - - for (size_t i = 0; i < len; i++) - PrintAndLogEx(NORMAL, "%02x " NOLF, data[i]); - - PrintAndLogEx(NORMAL, ""); -} - -void print_hex_break(const uint8_t *data, const size_t len, uint8_t breaks) { - if (data == NULL || len == 0 || breaks == 0) return; - - uint16_t rownum = 0; - int i; - for (i = 0; i < len; i += breaks, rownum++) { - if (len - i < breaks) { // incomplete block, will be treated out of the loop - break; - } - PrintAndLogEx(INFO, "%02u | %s", rownum, sprint_hex_ascii(data + i, breaks)); - } - - // the last odd bytes - uint8_t mod = len % breaks; - - if (mod) { - char buf[UTIL_BUFFER_SIZE_SPRINT + 3] = {0}; - hex_to_buffer((uint8_t *)buf, data + i, mod, (sizeof(buf) - 1), 0, 1, true); - - // add the spaces... - snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%*s", ((breaks - mod) * 3), " "); - snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "| %s", sprint_ascii(data + i, mod)); - PrintAndLogEx(INFO, "%02u | %s", rownum, buf); - } -} - -void print_hex_noascii_break(const uint8_t *data, const size_t len, uint8_t breaks) { - if (data == NULL || len == 0 || breaks == 0) return; - - int i; - for (i = 0; i < len; i += breaks) { - if (len - i < breaks) { // incomplete block, will be treated out of the loop - break; - } - PrintAndLogEx(INFO, "%s", sprint_hex_inrow_spaces(data + i, breaks, 0)); - } - - // the last odd bytes - uint8_t mod = len % breaks; - - if (mod) { - char buf[UTIL_BUFFER_SIZE_SPRINT + 3] = {0}; - hex_to_buffer((uint8_t *)buf, data + i, mod, (sizeof(buf) - 1), 0, 0, true); - - // add the spaces... - snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%*s", ((breaks - mod) * 3), " "); - PrintAndLogEx(INFO, "%s", buf); - } -} - -static void print_buffer_ex(const uint8_t *data, const size_t len, int level, uint8_t breaks) { - - // sanity checks - if ((data == NULL) || (len < 1)) - return; - - char buf[UTIL_BUFFER_SIZE_SPRINT + 3] = {0}; - int i; - for (i = 0; i < len; i += breaks) { - - memset(buf, 0x00, sizeof(buf)); - - if (len - i < breaks) { // incomplete block, will be treated out of the loop - break; - } - - // (16 * 3) + (16) + + 1 - snprintf(buf, sizeof(buf), "%*s%02x: ", (level * 4), " ", i); - - hex_to_buffer((uint8_t *)(buf + strlen(buf)), data + i, breaks, (sizeof(buf) - strlen(buf) - 1), 0, 1, true); - - snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "| %s", sprint_ascii(data + i, breaks)); - - PrintAndLogEx(INFO, "%s", buf); - } - - // the last odd bytes - uint8_t mod = len % breaks; - - if (mod) { - snprintf(buf, sizeof(buf), "%*s%02x: ", (level * 4), " ", i); - hex_to_buffer((uint8_t *)(buf + strlen(buf)), data + i, mod, (sizeof(buf) - strlen(buf) - 1), 0, 1, true); - - // add the spaces... - snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%*s", ((breaks - mod) * 3), " "); - - snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "| %s", sprint_ascii(data + i, mod)); - PrintAndLogEx(INFO, "%s", buf); - } -} - -void print_buffer(const uint8_t *data, const size_t len, int level) { - print_buffer_ex(data, len, level, 16); -} - -void print_buffer_with_offset(const uint8_t *data, const size_t len, int offset, bool print_header) { - if (print_header) { - PrintAndLogEx(INFO, " Offset | Data | Ascii"); - PrintAndLogEx(INFO, "----------------------------------------------------------------------------"); - } - - for (uint32_t i = 0; i < len; i += 16) { - uint32_t l = len - i; - PrintAndLogEx(INFO, "%3d/0x%02X | %s" NOLF, offset + i, offset + i, sprint_hex(&data[i], l > 16 ? 16 : l)); - if (l < 16) - PrintAndLogEx(NORMAL, "%*s" NOLF, 3 * (16 - l), " "); - PrintAndLogEx(NORMAL, "| %s", sprint_ascii(&data[i], l > 16 ? 16 : l)); - } -} - -void print_blocks(uint32_t *data, size_t len) { - PrintAndLogEx(SUCCESS, "Blk | Data "); - PrintAndLogEx(SUCCESS, "----+------------"); - - if (!data) { - PrintAndLogEx(ERR, "..empty data"); - } else { - for (size_t i = 0; i < len; i++) - PrintAndLogEx(SUCCESS, " %02zd | %08X", i, data[i]); - } -} - -char *sprint_hex(const uint8_t *data, const size_t len) { - static char buf[UTIL_BUFFER_SIZE_SPRINT] = {0}; - memset(buf, 0x00, sizeof(buf)); - hex_to_buffer((uint8_t *)buf, data, len, sizeof(buf) - 1, 0, 1, true); - return buf; -} - -char *sprint_hex_inrow_ex(const uint8_t *data, const size_t len, const size_t min_str_len) { - static char buf[UTIL_BUFFER_SIZE_SPRINT] = {0}; - memset(buf, 0x00, sizeof(buf)); - hex_to_buffer((uint8_t *)buf, data, len, sizeof(buf) - 1, min_str_len, 0, true); - return buf; -} - -char *sprint_hex_inrow(const uint8_t *data, const size_t len) { - return sprint_hex_inrow_ex(data, len, 0); -} - -char *sprint_hex_inrow_spaces(const uint8_t *data, const size_t len, size_t spaces_between) { - static char buf[UTIL_BUFFER_SIZE_SPRINT] = {0}; - memset(buf, 0x00, sizeof(buf)); - hex_to_buffer((uint8_t *)buf, data, len, sizeof(buf) - 1, 0, spaces_between, true); - return buf; -} - -char *sprint_bytebits_bin_break(const uint8_t *data, const size_t len, const uint8_t breaks) { - - // make sure we don't go beyond our char array memory - size_t rowlen = (len > MAX_BIN_BREAK_LENGTH) ? MAX_BIN_BREAK_LENGTH : len; - - // 3072 + end of line characters if broken at 8 bits - static char buf[MAX_BIN_BREAK_LENGTH] = {0}; - memset(buf, 0, sizeof(buf)); - - char *tmp = buf; - - // loop through the out_index to make sure we don't go too far - for (int i = 0; i < rowlen; i++) { - - char c = data[i]; - // manchester wrong bit marker - if (c == 7) { - c = '.'; - } else if (c < 2) { - c += '0'; - } else { - PrintAndLogEx(ERR, "Invalid data passed to sprint_bytebits_bin_break()"); - return buf; - } - - *(tmp++) = c; - - // check if a line break is needed and we have room to print it in our array - if (breaks > 1) { - if (((i + 1) % breaks) == 0) { - - *(tmp++) = '\n'; - } - } - } - return buf; -} -/* -void sprint_bin_break_ex(uint8_t *src, size_t srclen, char *dest , uint8_t breaks) { - if ( src == NULL ) return; - if ( srclen < 1 ) return; - - // make sure we don't go beyond our char array memory - size_t in_index = 0, out_index = 0; - int rowlen; - if (breaks==0) - rowlen = ( len > MAX_BIN_BREAK_LENGTH ) ? MAX_BIN_BREAK_LENGTH : len; - else - rowlen = ( len+(len/breaks) > MAX_BIN_BREAK_LENGTH ) ? MAX_BIN_BREAK_LENGTH : len+(len/breaks); - - PrintAndLogEx(NORMAL, "(sprint_bin_break) rowlen %d", rowlen); - - // 3072 + end of line characters if broken at 8 bits - dest = (char *)calloc(MAX_BIN_BREAK_LENGTH, sizeof(uint8_t)); - if (dest == NULL) return; - - //clear memory - memset(dest, 0x00, sizeof(dest)); - - // loop through the out_index to make sure we don't go too far - for (out_index=0; out_index < rowlen-1; out_index++) { - // set character - sprintf(dest++, "%u", src[in_index]); - // check if a line break is needed and we have room to print it in our array - if ( (breaks > 0) && !((in_index+1) % breaks) && (out_index+1 != rowlen) ) { - // increment and print line break - out_index++; - sprintf(dest++, "%s","\n"); - } - in_index++; - } - // last char. - sprintf(dest++, "%u", src[in_index]); -} -*/ - -char *sprint_bytebits_bin(const uint8_t *data, const size_t len) { - return sprint_bytebits_bin_break(data, len, 0); -} - -char *sprint_bin(const uint8_t *data, const size_t len) { - size_t binlen = (len * 8 > MAX_BIN_BREAK_LENGTH) ? MAX_BIN_BREAK_LENGTH : len * 8; - static uint8_t buf[MAX_BIN_BREAK_LENGTH] = {0}; - bytes_to_bytebits(data, binlen / 8, buf); - return sprint_bytebits_bin_break(buf, binlen, 0); -} - -char *sprint_hex_ascii(const uint8_t *data, const size_t len) { - static char buf[UTIL_BUFFER_SIZE_SPRINT + 20] = {0}; - memset(buf, 0x00, sizeof(buf)); - - char *tmp = buf; - size_t max_len = (len > 1010) ? 1010 : len; - - int ret = snprintf(buf, sizeof(buf) - 1, "%s| ", sprint_hex(data, max_len)); - if (ret < 0) { - goto out; - } - - size_t i = 0; - size_t pos = (max_len * 3) + 2; - - while (i < max_len) { - char c = data[i]; - tmp[pos + i] = ((c < 32) || (c == 127)) ? '.' : c; - ++i; - } -out: - return buf; -} - -char *sprint_ascii_ex(const uint8_t *data, const size_t len, const size_t min_str_len) { - static char buf[UTIL_BUFFER_SIZE_SPRINT] = {0}; - memset(buf, 0x00, sizeof(buf)); - - char *tmp = buf; - size_t max_len = (len > 1010) ? 1010 : len; - size_t i = 0; - - while (i < max_len) { - char c = data[i]; - tmp[i] = ((c < 32) || (c == 127)) ? '.' : c; - ++i; - } - - size_t m = min_str_len > i ? min_str_len : 0; - for (; i < m; ++i) - tmp[i] = ' '; - - return buf; -} -char *sprint_ascii(const uint8_t *data, const size_t len) { - return sprint_ascii_ex(data, len, 0); -} - -int hex_to_bytes(const char *hexValue, uint8_t *bytesValue, size_t maxBytesValueLen) { - char buf[4] = {0}; - int indx = 0; - int bytesValueLen = 0; - while (hexValue[indx]) { - if (hexValue[indx] == '\t' || hexValue[indx] == ' ') { - indx++; - continue; - } - - if (isxdigit(hexValue[indx])) { - buf[strlen(buf)] = hexValue[indx]; - } else { - // if we have symbols other than spaces and hex - return -1; - } - - if (maxBytesValueLen && bytesValueLen >= maxBytesValueLen) { - // if we don't have space in buffer and have symbols to translate - return -2; - } - - if (strlen(buf) >= 2) { - uint32_t temp = 0; - sscanf(buf, "%x", &temp); - bytesValue[bytesValueLen] = (uint8_t)(temp & 0xff); - memset(buf, 0, sizeof(buf)); - bytesValueLen++; - } - - indx++; - } - - if (strlen(buf) > 0) - //error when not completed hex bytes - return -3; - - return bytesValueLen; -} - -// takes a number (uint64_t) and creates a binarray in dest. -void num_to_bytebits(uint64_t n, size_t len, uint8_t *dest) { - while (len--) { - dest[len] = n & 1; - n >>= 1; - } -} - -// least significant bit (lsb) first -void num_to_bytebitsLSBF(uint64_t n, size_t len, uint8_t *dest) { - for (size_t i = 0 ; i < len ; ++i) { - dest[i] = n & 1; - n >>= 1; - } -} - -void bytes_to_bytebits(const void *src, const size_t srclen, void *dest) { - - uint8_t *s = (uint8_t *)src; - uint8_t *d = (uint8_t *)dest; - - uint32_t i = srclen * 8; - size_t j = srclen; - while (j--) { - uint8_t b = s[j]; - d[--i] = (b >> 0) & 1; - d[--i] = (b >> 1) & 1; - d[--i] = (b >> 2) & 1; - d[--i] = (b >> 3) & 1; - d[--i] = (b >> 4) & 1; - d[--i] = (b >> 5) & 1; - d[--i] = (b >> 6) & 1; - d[--i] = (b >> 7) & 1; - } -} - -// aa,bb,cc,dd,ee,ff,gg,hh, ii,jj,kk,ll,mm,nn,oo,pp -// to -// hh,gg,ff,ee,dd,cc,bb,aa, pp,oo,nn,mm,ll,kk,jj,ii -// up to 64 bytes or 512 bits -uint8_t *SwapEndian64(const uint8_t *src, const size_t len, const uint8_t blockSize) { - static uint8_t buf[64] = {0}; - memset(buf, 0x00, 64); - uint8_t *tmp = buf; - for (uint8_t block = 0; block < (uint8_t)(len / blockSize); block++) { - for (size_t i = 0; i < blockSize; i++) { - tmp[i + (blockSize * block)] = src[(blockSize - 1 - i) + (blockSize * block)]; - } - } - return buf; -} - -// takes a uint8_t src array, for len items and reverses the byte order in blocksizes (8,16,32,64), -// returns: the dest array contains the reordered src array. -void SwapEndian64ex(const uint8_t *src, const size_t len, const uint8_t blockSize, uint8_t *dest) { - for (uint8_t block = 0; block < (uint8_t)(len / blockSize); block++) { - for (size_t i = 0; i < blockSize; i++) { - dest[i + (blockSize * block)] = src[(blockSize - 1 - i) + (blockSize * block)]; - } - } -} - -// ------------------------------------------------------------------------- -// string parameters lib -// ------------------------------------------------------------------------- - -// ------------------------------------------------------------------------- -// line - param line -// bg, en - symbol numbers in param line of beginning and ending parameter -// paramnum - param number (from 0) -// ------------------------------------------------------------------------- -int param_getptr(const char *line, int *bg, int *en, int paramnum) { - int i; - int len = strlen(line); - - *bg = 0; - *en = 0; - - // skip spaces - while (line[*bg] == ' ' || line[*bg] == '\t')(*bg)++; - if (*bg >= len) { - return 1; - } - - for (i = 0; i < paramnum; i++) { - while (line[*bg] != ' ' && line[*bg] != '\t' && line[*bg] != '\0')(*bg)++; - while (line[*bg] == ' ' || line[*bg] == '\t')(*bg)++; - - if (line[*bg] == '\0') return 1; - } - - *en = *bg; - while (line[*en] != ' ' && line[*en] != '\t' && line[*en] != '\0')(*en)++; - - (*en)--; - - return 0; -} - -int param_getlength(const char *line, int paramnum) { - int bg, en; - - if (param_getptr(line, &bg, &en, paramnum)) return 0; - - return en - bg + 1; -} - -char param_getchar(const char *line, int paramnum) { - return param_getchar_indx(line, 0, paramnum); -} - -char param_getchar_indx(const char *line, int indx, int paramnum) { - int bg, en; - - if (param_getptr(line, &bg, &en, paramnum)) return 0x00; - - if (bg + indx > en) - return '\0'; - - return line[bg + indx]; -} - -uint8_t param_get8(const char *line, int paramnum) { - return param_get8ex(line, paramnum, 0, 10); -} - -/** - * @brief Reads a decimal integer (actually, 0-254, not 255) - * @param line - * @param paramnum - * @return -1 if error - */ -uint8_t param_getdec(const char *line, int paramnum, uint8_t *destination) { - uint8_t val = param_get8ex(line, paramnum, 255, 10); - if ((int8_t) val == -1) return 1; - (*destination) = val; - return 0; -} -/** - * @brief Checks if param is decimal - * @param line - * @param paramnum - * @return - */ -uint8_t param_isdec(const char *line, int paramnum) { - int bg, en; - //TODO, check more thorougly - if (!param_getptr(line, &bg, &en, paramnum)) return 1; - // return strtoul(&line[bg], NULL, 10) & 0xff; - - return 0; -} - -uint8_t param_get8ex(const char *line, int paramnum, int deflt, int base) { - int bg, en; - if (!param_getptr(line, &bg, &en, paramnum)) - return strtoul(&line[bg], NULL, base) & 0xff; - else - return deflt; -} - -uint32_t param_get32ex(const char *line, int paramnum, int deflt, int base) { - int bg, en; - if (!param_getptr(line, &bg, &en, paramnum)) - return strtoul(&line[bg], NULL, base); - else - return deflt; -} - -uint64_t param_get64ex(const char *line, int paramnum, int deflt, int base) { - int bg, en; - if (!param_getptr(line, &bg, &en, paramnum)) - return strtoull(&line[bg], NULL, base); - else - return deflt; -} - -float param_getfloat(const char *line, int paramnum, float deflt) { - int bg, en; - if (!param_getptr(line, &bg, &en, paramnum)) - return strtof(&line[bg], NULL); - else - return deflt; -} - -int param_gethex(const char *line, int paramnum, uint8_t *data, int hexcnt) { - int bg, en, i; - uint32_t temp; - - if (hexcnt & 1) return 1; - - if (param_getptr(line, &bg, &en, paramnum)) return 1; - - if (en - bg + 1 != hexcnt) return 1; - - for (i = 0; i < hexcnt; i += 2) { - if (!(isxdigit(line[bg + i]) && isxdigit(line[bg + i + 1]))) return 1; - - sscanf((char[]) {line[bg + i], line[bg + i + 1], 0}, "%X", &temp); - data[i / 2] = temp & 0xff; - } - - return 0; -} -int param_gethex_ex(const char *line, int paramnum, uint8_t *data, int *hexcnt) { - int bg, en, i; - uint32_t temp; - - if (param_getptr(line, &bg, &en, paramnum)) return 1; - - *hexcnt = en - bg + 1; - if (*hexcnt % 2) //error if not complete hex bytes - return 1; - - for (i = 0; i < *hexcnt; i += 2) { - if (!(isxdigit(line[bg + i]) && isxdigit(line[bg + i + 1]))) return 1; - - sscanf((char[]) {line[bg + i], line[bg + i + 1], 0}, "%X", &temp); - data[i / 2] = temp & 0xff; - } - - return 0; -} - -int param_gethex_to_eol(const char *line, int paramnum, uint8_t *data, int maxdatalen, int *datalen) { - - int bg, en; - - if (param_getptr(line, &bg, &en, paramnum)) - return 1; - - *datalen = 0; - char buf[5] = {0}; - - int indx = bg; - while (line[indx]) { - if (line[indx] == '\t' || line[indx] == ' ') { - indx++; - continue; - } - - if (isxdigit(line[indx])) { - buf[strlen(buf) + 1] = 0x00; - buf[strlen(buf)] = line[indx]; - } else { - // if we have symbols other than spaces and hex - return 1; - } - - if (*datalen >= maxdatalen) { - // if we don't have space in buffer and have symbols to translate - return 2; - } - - if (strlen(buf) >= 2) { - uint32_t temp = 0; - sscanf(buf, "%x", &temp); - data[*datalen] = (uint8_t)(temp & 0xFF); - *buf = 0; - (*datalen)++; - } - - indx++; - } - - if (strlen(buf) > 0) - //error when not completed hex bytes - return 3; - - return 0; -} - -int param_getbin_to_eol(const char *line, int paramnum, uint8_t *data, int maxdatalen, int *datalen) { - int bg, en; - if (param_getptr(line, &bg, &en, paramnum)) { - return 1; - } - - *datalen = 0; - char buf[5] = {0}; - int indx = bg; - while (line[indx]) { - if (line[indx] == '\t' || line[indx] == ' ') { - indx++; - continue; - } - - if (line[indx] == '0' || line[indx] == '1') { - buf[strlen(buf) + 1] = 0x00; - buf[strlen(buf)] = line[indx]; - } else { - // if we have symbols other than spaces and 0/1 - return 1; - } - - if (*datalen >= maxdatalen) { - // if we don't have space in buffer and have symbols to translate - return 2; - } - - if (strlen(buf) > 0) { - uint32_t temp = 0; - sscanf(buf, "%d", &temp); - data[*datalen] = (uint8_t)(temp & 0xff); - *buf = 0; - (*datalen)++; - } - - indx++; - } - return 0; -} - -int param_getstr(const char *line, int paramnum, char *str, size_t buffersize) { - int bg, en; - - if (param_getptr(line, &bg, &en, paramnum)) { - return 0; - } - - // Prevent out of bounds errors - if (en - bg + 1 >= buffersize) { - PrintAndLogEx(ERR, "out of bounds error: want %d bytes have %zu bytes\n", en - bg + 1 + 1, buffersize); - return 0; - } - - memcpy(str, line + bg, en - bg + 1); - str[en - bg + 1] = 0; - - return en - bg + 1; -} - -/* -The following methods comes from Rfidler sourcecode. -https://github.com/ApertureLabsLtd/RFIDler/blob/master/firmware/Pic32/RFIDler.X/src/ -*/ -// convert hex to sequence of 0/1 bit values -// returns number of bits converted -int hextobinarray(char *target, char *source) { - return hextobinarray_n(target, source, strlen(source)); -} - -int hextobinarray_n(char *target, char *source, int sourcelen) { - int i, count = 0; - char *start = source; - // process 4 bits (1 hex digit) at a time - while (sourcelen--) { - char x = *(source++); - // capitalize - if (x >= 'a' && x <= 'f') { - x -= 32; - } - // convert to numeric value - if (x >= '0' && x <= '9') { - x -= '0'; - } else if (x >= 'A' && x <= 'F') { - x -= 'A' - 10; - } else { - PrintAndLogEx(INFO, "(hextobinarray) discovered unknown character %c %d at idx %d of %s", x, x, (int16_t)(source - start), start); - return 0; - } - // output - for (i = 0 ; i < 4 ; ++i, ++count) { - *(target++) = (x >> (3 - i)) & 1; - } - } - - return count; -} - -// convert hex to human readable binary string -int hextobinstring(char *target, char *source) { - return hextobinstring_n(target, source, strlen(source)); -} - -int hextobinstring_n(char *target, char *source, int sourcelen) { - int length = hextobinarray_n(target, source, sourcelen); - if (length == 0) { - return 0; - } - binarraytobinstring(target, target, length); - return length; -} - -// convert binary array of 0x00/0x01 values to hex -// return number of bits converted -int binarraytohex(char *target, const size_t targetlen, const char *source, size_t srclen) { - uint8_t i = 0, x = 0; - uint32_t t = 0; // written target chars - uint32_t r = 0; // consumed bits - uint8_t w = 0; // wrong bits separator printed - for (size_t s = 0 ; s < srclen; s++) { - if ((source[s] == 0) || (source[s] == 1)) { - w = 0; - x += (source[s] << (3 - i)); - i++; - if (i == 4) { - if (t >= targetlen - 2) { - return r; - } - snprintf(target + t, targetlen - t, "%X", x); - t++; - r += 4; - x = 0; - i = 0; - } - } else { - if (i > 0) { - if (t >= targetlen - 5) { - return r; - } - snprintf(target + t, targetlen - t, "%X[%i]", x, i); - t += 4; - r += i; - x = 0; - i = 0; - w = 1; - } - if (w == 0) { - if (t >= targetlen - 2) { - return r; - } - snprintf(target + t, targetlen - t, " "); - t++; - } - r++; - } - } - return r; -} - -// convert binary array to human readable binary -void binarraytobinstring(char *target, char *source, int length) { - for (int i = 0 ; i < length; ++i) - *(target++) = *(source++) + '0'; - *target = '\0'; -} - -int binstring2binarray(uint8_t *target, char *source, int length) { - int count = 0; - char *start = source; - while (length--) { - char x = *(source++); - // convert from binary value - if (x >= '0' && x <= '1') - x -= '0'; - else { - PrintAndLogEx(WARNING, "(binstring2binarray) discovered unknown character %c %d at idx %d of %s", x, x, (int16_t)(source - start), start); - return 0; - } - *(target++) = x; - count++; - } - return count; -} - -// return parity bit required to match type -uint8_t GetParity(const uint8_t *bits, uint8_t type, int length) { - int x; - for (x = 0 ; length > 0 ; --length) - x += bits[length - 1]; - x %= 2; - return x ^ type; -} - -// add HID parity to binary array: EVEN prefix for 1st half of ID, ODD suffix for 2nd half -void wiegand_add_parity(uint8_t *target, uint8_t *source, uint8_t length) { - *(target++) = GetParity(source, EVEN, length / 2); - memcpy(target, source, length); - target += length; - *(target) = GetParity(source + length / 2, ODD, length / 2); -} - -// add HID parity to binary array: ODD prefix for 1st half of ID, EVEN suffix for 2nd half -void wiegand_add_parity_swapped(uint8_t *target, uint8_t *source, uint8_t length) { - *(target++) = GetParity(source, ODD, length / 2); - memcpy(target, source, length); - target += length; - *(target) = GetParity(source + length / 2, EVEN, length / 2); -} - -// Pack a bitarray into a uint32_t. -uint32_t PackBits(uint8_t start, uint8_t len, const uint8_t *bits) { - - if (len > 32) return 0; - - int i = start; - int j = len - 1; - uint32_t tmp = 0; - - for (; j >= 0; --j, ++i) - tmp |= bits[i] << j; - - return tmp; -} - -uint64_t HornerScheme(uint64_t num, uint64_t divider, uint64_t factor) { - uint64_t remaind = 0, quotient = 0, result = 0; - remaind = num % divider; - quotient = num / divider; - if (!(quotient == 0 && remaind == 0)) - result += HornerScheme(quotient, divider, factor) * factor + remaind; - return result; -} - // determine number of logical CPU cores (use for multithreaded functions) int num_CPUs(void) { #if defined(_WIN32) @@ -1092,142 +45,6 @@ int num_CPUs(void) { #endif } -void str_lower(char *s) { - for (size_t i = 0; i < strlen(s); i++) - s[i] = tolower(s[i]); -} - -void str_upper(char *s) { - strn_upper(s, strlen(s)); -} - -void strn_upper(char *s, size_t n) { - for (size_t i = 0; i < n; i++) - s[i] = toupper(s[i]); -} -// check for prefix in string -bool str_startswith(const char *s, const char *pre) { - return strncmp(pre, s, strlen(pre)) == 0; -} - -// check for suffix in string -bool str_endswith(const char *s, const char *suffix) { - size_t ls = strlen(s); - size_t lsuffix = strlen(suffix); - if (ls >= lsuffix) { - return strncmp(suffix, s + (ls - lsuffix), lsuffix) == 0; - } - return false; -} - -// Replace unprintable characters with a dot in char buffer -void clean_ascii(unsigned char *buf, size_t len) { - for (size_t i = 0; i < len; i++) { - if (!isprint(buf[i])) - buf[i] = '.'; - } -} - -// replace \r \n to \0 -void strcleanrn(char *buf, size_t len) { - strcreplace(buf, len, '\n', '\0'); - strcreplace(buf, len, '\r', '\0'); -} - -// replace char in buffer -void strcreplace(char *buf, size_t len, char from, char to) { - for (size_t i = 0; i < len; i++) { - if (buf[i] == from) - buf[i] = to; - } -} - - -char *str_dup(const char *src) { - return str_ndup(src, strlen(src)); -} -char *str_ndup(const char *src, size_t len) { - - char *dest = (char *) calloc(len + 1, sizeof(uint8_t)); - if (dest != NULL) { - memcpy(dest, src, len); - dest[len] = '\0'; - } - return dest; -} - -/** - * Converts a hex string to component "hi2", "hi" and "lo" 32-bit integers - * one nibble at a time. - * - * Returns the number of nibbles (4 bits) entered. - */ -int hexstring_to_u96(uint32_t *hi2, uint32_t *hi, uint32_t *lo, const char *str) { - uint32_t n = 0, i = 0; - - while (sscanf(&str[i++], "%1x", &n) == 1) { - *hi2 = (*hi2 << 4) | (*hi >> 28); - *hi = (*hi << 4) | (*lo >> 28); - *lo = (*lo << 4) | (n & 0xf); - } - return i - 1; -} - -/** - * Converts a binary string to component "hi2", "hi" and "lo" 32-bit integers, - * one bit at a time. - * - * Returns the number of bits entered. - */ -int binstring_to_u96(uint32_t *hi2, uint32_t *hi, uint32_t *lo, const char *str) { - uint32_t n = 0, i = 0; - - for (;;) { - - int res = sscanf(&str[i], "%1u", &n); - if ((res != 1) || (n > 1)) - break; - - *hi2 = (*hi2 << 1) | (*hi >> 31); - *hi = (*hi << 1) | (*lo >> 31); - *lo = (*lo << 1) | (n & 0x1); - - i++; - } - return i; -} - - -/** - * Converts a binary array to component "hi2", "hi" and "lo" 32-bit integers, - * one bit at a time. - * - * Returns the number of bits entered. - */ -int binarray_to_u96(uint32_t *hi2, uint32_t *hi, uint32_t *lo, const uint8_t *arr, int arrlen) { - int i = 0; - for (; i < arrlen; i++) { - uint8_t n = arr[i]; - if (n > 1) - break; - - *hi2 = (*hi2 << 1) | (*hi >> 31); - *hi = (*hi << 1) | (*lo >> 31); - *lo = (*lo << 1) | (n & 0x1); - } - return i; -} - -inline uint32_t bitcount32(uint32_t a) { -#if defined __GNUC__ - return __builtin_popcountl(a); -#else - a = a - ((a >> 1) & 0x55555555); - a = (a & 0x33333333) + ((a >> 2) & 0x33333333); - return (((a + (a >> 4)) & 0x0f0f0f0f) * 0x01010101) >> 24; -#endif -} - inline uint64_t bitcount64(uint64_t a) { #if defined __GNUC__ return __builtin_popcountll(a); @@ -1235,55 +52,4 @@ inline uint64_t bitcount64(uint64_t a) { PrintAndLogEx(FAILED, "Was not compiled with fct bitcount64"); return 0; #endif -} - -inline uint32_t leadingzeros32(uint32_t a) { -#if defined __GNUC__ - return __builtin_clz(a); -#else - PrintAndLogEx(FAILED, "Was not compiled with fct bitcount64"); - return 0; -#endif -} - -inline uint64_t leadingzeros64(uint64_t a) { -#if defined __GNUC__ - return __builtin_clzll(a); -#else - PrintAndLogEx(FAILED, "Was not compiled with fct bitcount64"); - return 0; -#endif -} - - -int byte_strstr(const uint8_t *src, size_t srclen, const uint8_t *pattern, size_t plen) { - - size_t max = srclen - plen + 1; - - for (size_t i = 0; i < max; i++) { - - // compare only first byte - if (src[i] != pattern[0]) - continue; - - // try to match rest of the pattern - for (int j = plen - 1; j >= 1; j--) { - - if (src[i + j] != pattern[j]) - break; - - if (j == 1) - return i; - } - } - return -1; -} - -void sb_append_char(smartbuf *sb, unsigned char c) { - if (sb->idx >= sb->size) { - sb->size *= 2; - sb->ptr = realloc(sb->ptr, sb->size); - } - sb->ptr[sb->idx] = c; - sb->idx++; -} +} \ No newline at end of file diff --git a/HardNestedSolver/pm3/util.h b/HardNestedSolver/pm3/util.h index 4dab9ae..c017e44 100755 --- a/HardNestedSolver/pm3/util.h +++ b/HardNestedSolver/pm3/util.h @@ -31,133 +31,10 @@ extern uint8_t g_debugMode; extern uint8_t g_printAndLog; -extern bool g_pendingPrompt; #define PRINTANDLOG_PRINT 1 #define PRINTANDLOG_LOG 2 -// Return error -#define PM3_RET_ERR(err, ...) { \ - PrintAndLogEx(ERR, __VA_ARGS__); \ - return err; \ -} - -#define PM3_RET_ERR_FREE(err, ...) { \ - CLIParserFree(ctx); \ - PrintAndLogEx(ERR, __VA_ARGS__); \ - return err; \ -} - -// RETurn IF ERRor -#define PM3_RET_IF_ERR(res) if (res != PM3_SUCCESS) { return res; } -#define PM3_RET_IF_ERR_WITH_MSG(res, ...) if (res != PM3_SUCCESS) { PrintAndLogEx(ERR, __VA_ARGS__); return res; } -#define PM3_RET_IF_ERR_MAYBE_MSG(res, verbose, ...) if (res != PM3_SUCCESS) { if (verbose) PrintAndLogEx(ERR, __VA_ARGS__); return res; } - -int kbd_enter_pressed(void); -void FillFileNameByUID(char *filenamePrefix, const uint8_t *uid, const char *ext, const int uidlen); -// fill buffer from structure [{uint8_t data, size_t length},...] -int FillBuffer(uint8_t *data, size_t maxDataLength, size_t *dataLength, ...); - -bool CheckStringIsHEXValue(const char *value); -void ascii_to_buffer(uint8_t *buf, const uint8_t *hex_data, const size_t hex_len, - const size_t hex_max_len, const size_t min_str_len); -void hex_to_buffer(uint8_t *buf, const uint8_t *hex_data, const size_t hex_len, - const size_t hex_max_len, const size_t min_str_len, const size_t spaces_between, - bool uppercase); - -void print_hex(const uint8_t *data, const size_t len); -void print_hex_break(const uint8_t *data, const size_t len, const uint8_t breaks); -void print_hex_noascii_break(const uint8_t *data, const size_t len, uint8_t breaks); - -char *sprint_hex(const uint8_t *data, const size_t len); -char *sprint_hex_inrow(const uint8_t *data, const size_t len); -char *sprint_hex_inrow_ex(const uint8_t *data, const size_t len, const size_t min_str_len); -char *sprint_hex_inrow_spaces(const uint8_t *data, const size_t len, size_t spaces_between); -char *sprint_bin(const uint8_t *data, const size_t len); -char *sprint_bytebits_bin(const uint8_t *data, const size_t len); -char *sprint_bytebits_bin_break(const uint8_t *data, const size_t len, const uint8_t breaks); -char *sprint_hex_ascii(const uint8_t *data, const size_t len); -char *sprint_ascii(const uint8_t *data, const size_t len); -char *sprint_ascii_ex(const uint8_t *data, const size_t len, const size_t min_str_len); - -void print_buffer_with_offset(const uint8_t *data, const size_t len, int offset, bool print_header); -void print_buffer(const uint8_t *data, const size_t len, int level); -void print_blocks(uint32_t *data, size_t len); - -int hex_to_bytes(const char *hexValue, uint8_t *bytesValue, size_t maxBytesValueLen); -void num_to_bytebits(uint64_t n, size_t len, uint8_t *dest); -void num_to_bytebitsLSBF(uint64_t n, size_t len, uint8_t *dest); -void bytes_to_bytebits(const void *src, const size_t srclen, void *dest); - -// Swap endian on arrays up to 64bytes. -uint8_t *SwapEndian64(const uint8_t *src, const size_t len, const uint8_t blockSize); -void SwapEndian64ex(const uint8_t *src, const size_t len, const uint8_t blockSize, uint8_t *dest); - -// parameter helper functions -int param_getlength(const char *line, int paramnum); -char param_getchar(const char *line, int paramnum); -char param_getchar_indx(const char *line, int indx, int paramnum); -int param_getptr(const char *line, int *bg, int *en, int paramnum); -uint8_t param_get8(const char *line, int paramnum); -uint8_t param_get8ex(const char *line, int paramnum, int deflt, int base); -uint32_t param_get32ex(const char *line, int paramnum, int deflt, int base); -uint64_t param_get64ex(const char *line, int paramnum, int deflt, int base); -float param_getfloat(const char *line, int paramnum, float deflt); -uint8_t param_getdec(const char *line, int paramnum, uint8_t *destination); -uint8_t param_isdec(const char *line, int paramnum); -int param_gethex(const char *line, int paramnum, uint8_t *data, int hexcnt); -int param_gethex_ex(const char *line, int paramnum, uint8_t *data, int *hexcnt); -int param_gethex_to_eol(const char *line, int paramnum, uint8_t *data, int maxdatalen, int *datalen); -int param_getbin_to_eol(const char *line, int paramnum, uint8_t *data, int maxdatalen, int *datalen); -int param_getstr(const char *line, int paramnum, char *str, size_t buffersize); - -int hextobinarray(char *target, char *source); -int hextobinarray_n(char *target, char *source, int sourcelen); - -int hextobinstring(char *target, char *source); -int hextobinstring_n(char *target, char *source, int sourcelen); - -int binarraytohex(char *target, const size_t targetlen, const char *source, size_t srclen); -void binarraytobinstring(char *target, char *source, int length); -int binstring2binarray(uint8_t *target, char *source, int length); - -uint8_t GetParity(const uint8_t *bits, uint8_t type, int length); -void wiegand_add_parity(uint8_t *target, uint8_t *source, uint8_t length); -void wiegand_add_parity_swapped(uint8_t *target, uint8_t *source, uint8_t length); - -//void xor(unsigned char *dst, unsigned char *src, size_t len); - -uint32_t PackBits(uint8_t start, uint8_t len, const uint8_t *bits); -uint64_t HornerScheme(uint64_t num, uint64_t divider, uint64_t factor); - int num_CPUs(void); // number of logical CPUs -void str_lower(char *s); // converts string to lower case -void str_upper(char *s); // converts string to UPPER case -void strn_upper(char *s, size_t n); - -bool str_startswith(const char *s, const char *pre); // check for prefix in string -bool str_endswith(const char *s, const char *suffix); // check for suffix in string -void clean_ascii(unsigned char *buf, size_t len); -void strcleanrn(char *buf, size_t len); -void strcreplace(char *buf, size_t len, char from, char to); -char *str_dup(const char *src); -char *str_ndup(const char *src, size_t len); -int hexstring_to_u96(uint32_t *hi2, uint32_t *hi, uint32_t *lo, const char *str); -int binstring_to_u96(uint32_t *hi2, uint32_t *hi, uint32_t *lo, const char *str); -int binarray_to_u96(uint32_t *hi2, uint32_t *hi, uint32_t *lo, const uint8_t *arr, int arrlen); - -uint32_t bitcount32(uint32_t a); -uint64_t bitcount64(uint64_t a); -uint32_t leadingzeros32(uint32_t a); -uint64_t leadingzeros64(uint64_t a); - -int byte_strstr(const uint8_t *src, size_t srclen, const uint8_t *pattern, size_t plen); - -struct smartbuf { - char *ptr; - size_t size; - size_t idx; -} typedef smartbuf; -void sb_append_char(smartbuf *sb, unsigned char c); #endif diff --git a/HardNestedSolver/pm3/util_darwin.h b/HardNestedSolver/pm3/util_darwin.h deleted file mode 100755 index 5c80033..0000000 --- a/HardNestedSolver/pm3/util_darwin.h +++ /dev/null @@ -1,34 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// See LICENSE.txt for the text of the license. -//----------------------------------------------------------------------------- -// macOS framework bindings -//----------------------------------------------------------------------------- - -#ifndef UTIL_DARWIN_H__ -#define UTIL_DARWIN_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -void disableAppNap(const char *reason); -void enableAppNap(void); -void makeUnfocusable(void); -void makeFocusable(void); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/HardNestedSolver/pm3/util_darwin.m b/HardNestedSolver/pm3/util_darwin.m deleted file mode 100755 index 7e98e64..0000000 --- a/HardNestedSolver/pm3/util_darwin.m +++ /dev/null @@ -1,103 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// See LICENSE.txt for the text of the license. -//----------------------------------------------------------------------------- -// macOS framework bindings -//----------------------------------------------------------------------------- - -#import "util_darwin.h" - -#import -#import - -#if TARGET_OS_IOS -#import -#else -#import -#endif - -#if !defined(USING_ARC) -# if __has_feature(objc_arc) -# define USING_ARC 1 -# else -# define USING_ARC 0 -# endif -#elif EMPTY_DEFINE(USING_ARC) -# undef USING_ARC -# define USING_ARC 1 -#endif - -static id activity = nil; - -//OS X Version 10.10 is defined in OS X 10.10 and later -#if defined(MAC_OS_X_VERSION_10_10) -#if USING_ARC -@implementation AppDelegate { - id activity; -} -void disableAppNap(const char* reason) { - if(activity == nil) { - //NSLog(@"disableAppNap: %@", @(reason)); - activity = [[NSProcessInfo processInfo] beginActivityWithOptions:NSActivityBackground reason:@(reason)]; - } -} - -void enableAppNap() { - if(activity != nil) { - //NSLog(@"enableAppNap"); - [[NSProcessInfo processInfo] endActivity:activity]; - activity = nil; - } -} -@end -#else -void disableAppNap(const char* reason) { - if(activity == nil) { - //NSLog(@"disableAppNap: %@", @(reason)); - activity = [[NSProcessInfo processInfo] beginActivityWithOptions:NSActivityBackground reason:@(reason)]; - [activity retain]; - } -} - -void enableAppNap() { - if(activity != nil) { - //NSLog(@"enableAppNap"); - [[NSProcessInfo processInfo] endActivity:activity]; - [activity release]; - activity = nil; - } -} -#endif - -#else -void disableAppNap(const char* reason) { } -void enableAppNap() { } -#endif - - -#if TARGET_OS_IOS -void makeUnfocusable() { } -void makeFocusable() { } -//OS X Version 10.6 is defined in OS X 10.6 and later -#elif defined(MAC_OS_X_VERSION_10_6) -void makeUnfocusable() { - [NSApp setActivationPolicy:NSApplicationActivationPolicyProhibited]; -} -void makeFocusable() { - [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; -} -#else -void makeUnfocusable() { } -void makeFocusable() { } -#endif diff --git a/setup.py b/setup.py index 83ad4e8..30747c4 100644 --- a/setup.py +++ b/setup.py @@ -1,78 +1,56 @@ +import os from distutils.core import Extension + import setuptools -import os include_dirs = [] extra_compile_args = [] -libraries = ['lzma'] +libraries = ["lzma"] -if os.name == 'nt': - include_dirs = ['build\\pthreads', 'build\\lzma'] - extra_compile_args = ['-DNEED_FTIME'] - libraries.extend(['pthreadVC2', 'Ws2_32']) +if os.name == "nt": + include_dirs = ["build\\pthreads", "build\\lzma"] + extra_compile_args = ["-DNEED_FTIME"] + libraries.extend(["pthreadVC2", "Ws2_32"]) -nested_solver = Extension('nested', - sources=['NestedSolver/python.c', 'NestedSolver/crapto1.c', 'NestedSolver/library.c', - 'NestedSolver/bucketsort.c', 'NestedSolver/crypto1.c', 'NestedSolver/progress.c'], +nested_solver = Extension("nested", + sources=["NestedSolver/python.c", "NestedSolver/crapto1.c", "NestedSolver/library.c", + "NestedSolver/bucketsort.c", "NestedSolver/crypto1.c", "NestedSolver/progress.c"], include_dirs=include_dirs, library_dirs=include_dirs, extra_compile_args=extra_compile_args, libraries=libraries) -hardnested_solver = Extension('hardnested', - sources=['HardNestedSolver/pm3/crc32.c', 'HardNestedSolver/pm3/uart/uart_posix.c', - 'HardNestedSolver/pm3/uart/uart_win32.c', 'HardNestedSolver/pm3/crc.c', - 'HardNestedSolver/pm3/ui.c', 'HardNestedSolver/pm3/fileutils.c', - 'HardNestedSolver/pm3/crc16.c', 'HardNestedSolver/pm3/util.c', - 'HardNestedSolver/pm3/util_posix.c', 'HardNestedSolver/pm3/commonutil.c', - 'HardNestedSolver/pm3/crc64.c', 'HardNestedSolver/cmdhfmfhard.c', - 'HardNestedSolver/crapto1.c', 'HardNestedSolver/bucketsort.c', - 'HardNestedSolver/crypto1.c', 'HardNestedSolver/library.c', - 'HardNestedSolver/hardnested/hardnested_bf_core.c', - 'HardNestedSolver/hardnested/hardnested_bruteforce.c', - 'HardNestedSolver/hardnested/hardnested_bitarray_core.c', - 'HardNestedSolver/hardnested/tables.c', - 'HardNestedSolver/python.c'], - include_dirs=include_dirs, library_dirs=include_dirs, - extra_compile_args=extra_compile_args, - libraries=libraries) +hardnested_solver = Extension("hardnested", sources=["HardNestedSolver/pm3/ui.c", "HardNestedSolver/pm3/util.c", + "HardNestedSolver/cmdhfmfhard.c", "HardNestedSolver/library.c", + "HardNestedSolver/pm3/commonutil.c", "HardNestedSolver/crapto1.c", + "HardNestedSolver/bucketsort.c", "HardNestedSolver/crypto1.c", + "HardNestedSolver/hardnested/hardnested_bf_core.c", + "HardNestedSolver/hardnested/hardnested_bruteforce.c", + "HardNestedSolver/hardnested/hardnested_bitarray_core.c", + "HardNestedSolver/hardnested/tables.c", + "HardNestedSolver/python.c"], include_dirs=include_dirs, + library_dirs=include_dirs, extra_compile_args=extra_compile_args, libraries=libraries) with open("README.md", "r") as fh: long_description = fh.read() -setuptools.setup( - name="FlipperNested", - version="2.1.3", - author="AloneLiberty", - description="Recover keys from collected nonces", - long_description=long_description, - long_description_content_type="text/markdown", - url="https://github.com/AloneLiberty/FlipperNestedRecovery", - entry_points={'console_scripts': ['FlipperNested = FlipperNested.cli:main']}, - install_requires=['protobuf>4', 'pyserial'], - ext_modules=[nested_solver, hardnested_solver], - packages=["FlipperNested", "FlipperNested.proto"], - python_requires='>=3.8', - classifiers=[ - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", - "Operating System :: MacOS", - "Operating System :: POSIX :: Linux", - "Operating System :: Microsoft :: Windows" - ], - headers=['NestedSolver/library.h', 'NestedSolver/parity.h', - 'NestedSolver/crapto1.h', 'NestedSolver/bucketsort.h', - 'NestedSolver/progress.h', 'HardNestedSolver/pm3/util_darwin.h', 'HardNestedSolver/pm3/uart/uart.h', - 'HardNestedSolver/pm3/pm3_cmd.h', 'HardNestedSolver/pm3/util.h', 'HardNestedSolver/pm3/ui.h', - 'HardNestedSolver/pm3/crc64.h', 'HardNestedSolver/pm3/common.h', 'HardNestedSolver/pm3/fileutils.h', - 'HardNestedSolver/pm3/util_posix.h', 'HardNestedSolver/pm3/ansi.h', 'HardNestedSolver/pm3/crc32.h', - 'HardNestedSolver/pm3/crc.h', 'HardNestedSolver/pm3/commonutil.h', 'HardNestedSolver/pm3/comms.h', - 'HardNestedSolver/pm3/emojis_alt.h', 'HardNestedSolver/pm3/crc16.h', 'HardNestedSolver/pm3/emojis.h', - 'HardNestedSolver/bucketsort.h', 'HardNestedSolver/crapto1.h', 'HardNestedSolver/parity.h', - 'HardNestedSolver/hardnested/hardnested_benchmark_data.h', - 'HardNestedSolver/hardnested/hardnested_bf_core.h', - 'HardNestedSolver/hardnested/hardnested_bitarray_core.h', - 'HardNestedSolver/hardnested/hardnested_bruteforce.h', 'HardNestedSolver/hardnested/tables.h', - 'HardNestedSolver/library.h', 'HardNestedSolver/cmdhfmfhard.h'], -) +setuptools.setup(name="FlipperNested", version="2.2.0", author="AloneLiberty", + description="Recover keys from collected nonces", long_description=long_description, + long_description_content_type="text/markdown", + url="https://github.com/AloneLiberty/FlipperNestedRecovery", + entry_points={"console_scripts": ["FlipperNested = FlipperNested.cli:main"]}, + install_requires=["protobuf>4", "pyserial"], ext_modules=[nested_solver, hardnested_solver], + packages=["FlipperNested", "FlipperNested.proto"], python_requires=">=3.8", + classifiers=["Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", + "Operating System :: MacOS", "Operating System :: POSIX :: Linux", + "Operating System :: Microsoft :: Windows"], + headers=["HardNestedSolver/pm3/util.h", "HardNestedSolver/pm3/ui.h", "HardNestedSolver/pm3/common.h", + "HardNestedSolver/pm3/util_posix.h", "HardNestedSolver/pm3/ansi.h", + "HardNestedSolver/pm3/commonutil.h", "HardNestedSolver/pm3/emojis_alt.h", + "HardNestedSolver/pm3/emojis.h", "HardNestedSolver/bucketsort.h", + "HardNestedSolver/crapto1.h", "HardNestedSolver/parity.h", + "HardNestedSolver/hardnested/hardnested_benchmark_data.h", + "HardNestedSolver/hardnested/hardnested_bf_core.h", + "HardNestedSolver/hardnested/hardnested_bitarray_core.h", + "HardNestedSolver/hardnested/hardnested_bruteforce.h", "HardNestedSolver/hardnested/tables.h", + "HardNestedSolver/library.h", "HardNestedSolver/cmdhfmfhard.h"])