diff --git a/.gitconfig b/.gitconfig new file mode 100644 index 000000000..83575d662 --- /dev/null +++ b/.gitconfig @@ -0,0 +1,3 @@ +[user] + email = iceman@iuse.se + name = iceman1001 diff --git a/client/hardnested/bf_bench_data.bin b/client/hardnested/bf_bench_data.bin new file mode 100644 index 000000000..30734da93 Binary files /dev/null and b/client/hardnested/bf_bench_data.bin differ diff --git a/client/hardnested/hardnested_bf_core.c b/client/hardnested/hardnested_bf_core.c new file mode 100644 index 000000000..2388f6f54 --- /dev/null +++ b/client/hardnested/hardnested_bf_core.c @@ -0,0 +1,603 @@ +//----------------------------------------------------------------------------- +// Copyright (C) 2016, 2017 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 +//----------------------------------------------------------------------------- +// +// brute forcing is based on @aczids bitsliced brute forcer +// https://github.com/aczid/crypto1_bs with some modifications. Mainly: +// - don't rollback. Start with 2nd byte of nonce instead +// - reuse results of filter subfunctions +// - reuse results of previous nonces if some first bits are identical +// +//----------------------------------------------------------------------------- +// aczid's Copyright notice: +// +// Bit-sliced Crypto-1 brute-forcing implementation +// Builds on the data structures returned by CraptEV1 craptev1_get_space(nonces, threshold, uid) +/* +Copyright (c) 2015-2016 Aram Verstegen + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#include "hardnested_bf_core.h" + +#include +#include +#include +#ifndef __APPLE__ +#include +#endif +#include +#include +#include "crapto1/crapto1.h" +#include "parity.h" + +// bitslice type +// while AVX supports 256 bit vector floating point operations, we need integer operations for boolean logic +// same for AVX2 and 512 bit vectors +// using larger vectors works but seems to generate more register pressure +#if defined(__AVX512F__) +#define MAX_BITSLICES 512 +#elif defined(__AVX2__) +#define MAX_BITSLICES 256 +#elif defined(__AVX__) +#define MAX_BITSLICES 128 +#elif defined(__SSE2__) +#define MAX_BITSLICES 128 +#else // MMX or SSE or NOSIMD +#define MAX_BITSLICES 64 +#endif + +#define VECTOR_SIZE (MAX_BITSLICES/8) +typedef unsigned int __attribute__((aligned(VECTOR_SIZE))) __attribute__((vector_size(VECTOR_SIZE))) bitslice_value_t; +typedef union { + bitslice_value_t value; + uint64_t bytes64[MAX_BITSLICES/64]; + uint8_t bytes[MAX_BITSLICES/8]; +} bitslice_t; + +// filter function (f20) +// sourced from ``Wirelessly Pickpocketing a Mifare Classic Card'' by Flavio Garcia, Peter van Rossum, Roel Verdult and Ronny Wichers Schreur +#define f20a(a,b,c,d) (((a|b)^(a&d))^(c&((a^b)|d))) +#define f20b(a,b,c,d) (((a&b)|c)^((a^b)&(c|d))) +#define f20c(a,b,c,d,e) ((a|((b|e)&(d^e)))^((a^(b&d))&((c^d)|(b&e)))) + +// bit indexing +#define get_bit(n, word) (((word) >> (n)) & 1) +#define get_vector_bit(slice, value) get_bit((slice)&0x3f, value.bytes64[(slice)>>6]) + +// size of crypto-1 state +#define STATE_SIZE 48 +// size of nonce to be decrypted +#define KEYSTREAM_SIZE 24 + +// endianness conversion +#define rev32(word) ((((word) & 0xff) << 24) | ((((word) >> 8) & 0xff) << 16) | ((((word) >> 16) & 0xff) << 8) | ((((word) >> 24) & 0xff))) + +// this needs to be compiled several times for each instruction set. +// For each instruction set, define a dedicated function name: +#if defined (__AVX512F__) +#define BITSLICE_TEST_NONCES bitslice_test_nonces_AVX512 +#define CRACK_STATES_BITSLICED crack_states_bitsliced_AVX512 +#elif defined (__AVX2__) +#define BITSLICE_TEST_NONCES bitslice_test_nonces_AVX2 +#define CRACK_STATES_BITSLICED crack_states_bitsliced_AVX2 +#elif defined (__AVX__) +#define BITSLICE_TEST_NONCES bitslice_test_nonces_AVX +#define CRACK_STATES_BITSLICED crack_states_bitsliced_AVX +#elif defined (__SSE2__) +#define BITSLICE_TEST_NONCES bitslice_test_nonces_SSE2 +#define CRACK_STATES_BITSLICED crack_states_bitsliced_SSE2 +#elif defined (__MMX__) +#define BITSLICE_TEST_NONCES bitslice_test_nonces_MMX +#define CRACK_STATES_BITSLICED crack_states_bitsliced_MMX +#else +#define BITSLICE_TEST_NONCES bitslice_test_nonces_NOSIMD +#define CRACK_STATES_BITSLICED crack_states_bitsliced_NOSIMD +#endif + +// typedefs and declaration of functions: +typedef const uint64_t crack_states_bitsliced_t(uint32_t, uint8_t*, statelist_t*, uint32_t*, uint64_t*, uint32_t, uint8_t*, noncelist_t*); +crack_states_bitsliced_t crack_states_bitsliced_AVX512; +crack_states_bitsliced_t crack_states_bitsliced_AVX2; +crack_states_bitsliced_t crack_states_bitsliced_AVX; +crack_states_bitsliced_t crack_states_bitsliced_SSE2; +crack_states_bitsliced_t crack_states_bitsliced_MMX; +crack_states_bitsliced_t crack_states_bitsliced_NOSIMD; +crack_states_bitsliced_t crack_states_bitsliced_dispatch; + +typedef void bitslice_test_nonces_t(uint32_t, uint32_t*, uint8_t*); +bitslice_test_nonces_t bitslice_test_nonces_AVX512; +bitslice_test_nonces_t bitslice_test_nonces_AVX2; +bitslice_test_nonces_t bitslice_test_nonces_AVX; +bitslice_test_nonces_t bitslice_test_nonces_SSE2; +bitslice_test_nonces_t bitslice_test_nonces_MMX; +bitslice_test_nonces_t bitslice_test_nonces_NOSIMD; +bitslice_test_nonces_t bitslice_test_nonces_dispatch; + +#if defined (_WIN32) +#define malloc_bitslice(x) __builtin_assume_aligned(_aligned_malloc((x), MAX_BITSLICES/8), MAX_BITSLICES/8) +#define free_bitslice(x) _aligned_free(x) +#elif defined (__APPLE__) +static void *malloc_bitslice(size_t x) { + char *allocated_memory; + if (posix_memalign((void**)&allocated_memory, MAX_BITSLICES/8, x)) { + return NULL; + } else { + return __builtin_assume_aligned(allocated_memory, MAX_BITSLICES/8); + } +} +#define free_bitslice(x) free(x) +#else +#define malloc_bitslice(x) memalign(MAX_BITSLICES/8, (x)) +#define free_bitslice(x) free(x) +#endif + +typedef enum { + EVEN_STATE = 0, + ODD_STATE = 1 +} odd_even_t; + + +// arrays of bitsliced states with identical values in all slices +static bitslice_t bitsliced_encrypted_nonces[256][KEYSTREAM_SIZE]; +static bitslice_t bitsliced_encrypted_parity_bits[256][4]; +// 1 and 0 vectors +static bitslice_t bs_ones; +static bitslice_t bs_zeroes; + + +void BITSLICE_TEST_NONCES(uint32_t nonces_to_bruteforce, uint32_t *bf_test_nonce, uint8_t *bf_test_nonce_par) { + + // initialize 1 and 0 vectors + memset(bs_ones.bytes, 0xff, VECTOR_SIZE); + memset(bs_zeroes.bytes, 0x00, VECTOR_SIZE); + + // bitslice nonces' 2nd to 4th byte + for (uint32_t i = 0; i < nonces_to_bruteforce; i++) { + for(uint32_t bit_idx = 0; bit_idx < KEYSTREAM_SIZE; bit_idx++){ + bool bit = get_bit(KEYSTREAM_SIZE-1-bit_idx, rev32(bf_test_nonce[i] << 8)); + if(bit){ + bitsliced_encrypted_nonces[i][bit_idx].value = bs_ones.value; + } else { + bitsliced_encrypted_nonces[i][bit_idx].value = bs_zeroes.value; + } + } + } + // bitslice nonces' parity (4 bits) + for (uint32_t i = 0; i < nonces_to_bruteforce; i++) { + for(uint32_t bit_idx = 0; bit_idx < 4; bit_idx++){ + bool bit = get_bit(4-1-bit_idx, bf_test_nonce_par[i]); + if(bit){ + bitsliced_encrypted_parity_bits[i][bit_idx].value = bs_ones.value; + } else { + bitsliced_encrypted_parity_bits[i][bit_idx].value = bs_zeroes.value; + } + } + } + +} + + +const uint64_t CRACK_STATES_BITSLICED(uint32_t cuid, uint8_t *best_first_bytes, statelist_t *p, uint32_t *keys_found, uint64_t *num_keys_tested, uint32_t nonces_to_bruteforce, uint8_t *bf_test_nonce_2nd_byte, noncelist_t *nonces){ + + // Unlike aczid's implementation this doesn't roll back at all when performing bitsliced bruteforce. + // We know that the best first byte is already shifted in. Testing with the remaining three bytes of + // the nonces is sufficient to eliminate most of them. The small rest is tested with a simple unsliced + // brute forcing (including roll back). + + bitslice_t states[KEYSTREAM_SIZE+STATE_SIZE]; + bitslice_t * restrict state_p; + uint64_t key = -1; + uint64_t bucket_states_tested = 0; + uint32_t bucket_size[(p->len[EVEN_STATE] - 1)/MAX_BITSLICES + 1]; + uint32_t bitsliced_blocks = 0; + uint32_t const *restrict p_even_end = p->states[EVEN_STATE] + p->len[EVEN_STATE]; +#if defined (DEBUG_BRUTE_FORCE) + uint32_t elimination_step = 0; + #define MAX_ELIMINATION_STEP 32 + uint64_t keys_eliminated[MAX_ELIMINATION_STEP] = {0}; +#endif +#ifdef DEBUG_KEY_ELIMINATION + bool bucket_contains_test_key[(p->len[EVEN_STATE] - 1)/MAX_BITSLICES + 1]; +#endif + + // constant ones/zeroes + bitslice_t bs_ones; + memset(bs_ones.bytes, 0xff, VECTOR_SIZE); + bitslice_t bs_zeroes; + memset(bs_zeroes.bytes, 0x00, VECTOR_SIZE); + + // bitslice all the even states + bitslice_t **restrict bitsliced_even_states = (bitslice_t **)malloc(((p->len[EVEN_STATE] - 1)/MAX_BITSLICES + 1) * sizeof(bitslice_t *)); + if (bitsliced_even_states == NULL) { + printf("Out of memory error in brute_force. Aborting..."); + exit(4); + } + bitslice_value_t *restrict bitsliced_even_feedback = malloc_bitslice(((p->len[EVEN_STATE] - 1)/MAX_BITSLICES + 1) * sizeof(bitslice_value_t)); + if (bitsliced_even_feedback == NULL) { + printf("Out of memory error in brute_force. Aborting..."); + exit(4); + } + for(uint32_t *restrict p_even = p->states[EVEN_STATE]; p_even < p_even_end; p_even += MAX_BITSLICES){ + bitslice_t *restrict lstate_p = malloc_bitslice(STATE_SIZE/2*sizeof(bitslice_t)); + if (lstate_p == NULL) { + printf("Out of memory error in brute_force. Aborting... \n"); + exit(4); + } + memset(lstate_p, 0x00, STATE_SIZE/2*sizeof(bitslice_t)); // zero even bits + // bitslice even half-states + const uint32_t max_slices = (p_even_end-p_even) < MAX_BITSLICES ? p_even_end-p_even : MAX_BITSLICES; + bucket_size[bitsliced_blocks] = max_slices; +#ifdef DEBUG_KEY_ELIMINATION + bucket_contains_test_key[bitsliced_blocks] = false; +#endif + uint32_t slice_idx; + for(slice_idx = 0; slice_idx < max_slices; ++slice_idx){ + uint32_t e = *(p_even+slice_idx); +#ifdef DEBUG_KEY_ELIMINATION + if (known_target_key != -1 && e == test_state[EVEN_STATE]) { + bucket_contains_test_key[bitsliced_blocks] = true; + // printf("bucket %d contains test key even state\n", bitsliced_blocks); + // printf("in slice %d\n", slice_idx); + } +#endif + for(uint32_t bit_idx = 0; bit_idx < STATE_SIZE/2; bit_idx++, e >>= 1){ + // set even bits + if(e&1){ + lstate_p[bit_idx].bytes64[slice_idx>>6] |= 1ull << (slice_idx & 0x3f); + } + } + } + // padding with last even state + for ( ; slice_idx < MAX_BITSLICES; ++slice_idx) { + uint32_t e = *(p_even_end-1); + for(uint32_t bit_idx = 0; bit_idx < STATE_SIZE/2; bit_idx++, e >>= 1){ + // set even bits + if(e&1){ + lstate_p[bit_idx].bytes64[slice_idx>>6] |= 1ull << (slice_idx & 0x3f); + } + } + } + bitsliced_even_states[bitsliced_blocks] = lstate_p; + // bitsliced_even_feedback[bitsliced_blocks] = bs_ones; + bitsliced_even_feedback[bitsliced_blocks] = lstate_p[(47- 0)/2].value ^ + lstate_p[(47-10)/2].value ^ lstate_p[(47-12)/2].value ^ lstate_p[(47-14)/2].value ^ + lstate_p[(47-24)/2].value ^ lstate_p[(47-42)/2].value; + bitsliced_blocks++; + } + // bitslice every odd state to every block of even states + for(uint32_t const *restrict p_odd = p->states[ODD_STATE]; p_odd < p->states[ODD_STATE] + p->len[ODD_STATE]; ++p_odd){ + // early abort + if(*keys_found){ + goto out; + } + + // set odd state bits and pre-compute first keystream bit vector. This is the same for all blocks of even states + + state_p = &states[KEYSTREAM_SIZE]; + uint32_t o = *p_odd; + + // pre-compute the odd feedback bit + bool odd_feedback_bit = evenparity32(o&0x29ce5c); + const bitslice_value_t odd_feedback = odd_feedback_bit ? bs_ones.value : bs_zeroes.value; + + // set odd state bits + for (uint32_t state_idx = 0; state_idx < STATE_SIZE; o >>= 1, state_idx += 2) { + if (o & 1){ + state_p[state_idx] = bs_ones; + } else { + state_p[state_idx] = bs_zeroes; + } + } + + bitslice_value_t crypto1_bs_f20b_2[16]; + bitslice_value_t crypto1_bs_f20b_3[8]; + + crypto1_bs_f20b_2[0] = f20b(state_p[47-25].value, state_p[47-27].value, state_p[47-29].value, state_p[47-31].value); + crypto1_bs_f20b_3[0] = f20b(state_p[47-41].value, state_p[47-43].value, state_p[47-45].value, state_p[47-47].value); + + bitslice_value_t ksb[8]; + ksb[0] = f20c(f20a(state_p[47- 9].value, state_p[47-11].value, state_p[47-13].value, state_p[47-15].value), + f20b(state_p[47-17].value, state_p[47-19].value, state_p[47-21].value, state_p[47-23].value), + crypto1_bs_f20b_2[0], + f20a(state_p[47-33].value, state_p[47-35].value, state_p[47-37].value, state_p[47-39].value), + crypto1_bs_f20b_3[0]); + + uint32_t *restrict p_even = p->states[EVEN_STATE]; + for (uint32_t block_idx = 0; block_idx < bitsliced_blocks; ++block_idx, p_even += MAX_BITSLICES) { + +#ifdef DEBUG_KEY_ELIMINATION + // if (known_target_key != -1 && bucket_contains_test_key[block_idx] && *p_odd == test_state[ODD_STATE]) { + // printf("Now testing known target key.\n"); + // printf("block_idx = %d/%d\n", block_idx, bitsliced_blocks); + // } +#endif + // add the even state bits + const bitslice_t const *restrict bitsliced_even_state = bitsliced_even_states[block_idx]; + for(uint32_t state_idx = 1; state_idx < STATE_SIZE; state_idx += 2) { + state_p[state_idx] = bitsliced_even_state[state_idx/2]; + } + + // pre-compute first feedback bit vector. This is the same for all nonces + bitslice_value_t fbb[8]; + fbb[0] = odd_feedback ^ bitsliced_even_feedback[block_idx]; + + // vector to contain test results (1 = passed, 0 = failed) + bitslice_t results = bs_ones; + + // parity_bits + bitslice_value_t par[8]; + par[0] = bs_zeroes.value; + uint32_t next_common_bits = 0; + + for(uint32_t tests = 0; tests < nonces_to_bruteforce; ++tests){ + // common bits with preceding test nonce + uint32_t common_bits = next_common_bits; //tests ? trailing_zeros(bf_test_nonce_2nd_byte[tests] ^ bf_test_nonce_2nd_byte[tests-1]) : 0; + next_common_bits = tests < nonces_to_bruteforce - 1 ? trailing_zeros(bf_test_nonce_2nd_byte[tests] ^ bf_test_nonce_2nd_byte[tests+1]) : 0; + uint32_t parity_bit_idx = 1; // start checking with the parity of second nonce byte + bitslice_value_t fb_bits = fbb[common_bits]; // start with precomputed feedback bits from previous nonce + bitslice_value_t ks_bits = ksb[common_bits]; // dito for first keystream bits + bitslice_value_t parity_bit_vector = par[common_bits]; // dito for first parity vector + // bitslice_value_t fb_bits = fbb[0]; // start with precomputed feedback bits from previous nonce + // bitslice_value_t ks_bits = ksb[0]; // dito for first keystream bits + // bitslice_value_t parity_bit_vector = par[0]; // dito for first parity vector + state_p -= common_bits; // and reuse the already calculated state bits + // highest bit is transmitted/received first. We start with Bit 23 (highest bit of second nonce byte), + // or the highest bit which differs from the previous nonce + for (int32_t ks_idx = KEYSTREAM_SIZE-1-common_bits; ks_idx >= 0; --ks_idx) { + + // decrypt nonce bits + const bitslice_value_t encrypted_nonce_bit_vector = bitsliced_encrypted_nonces[tests][ks_idx].value; + const bitslice_value_t decrypted_nonce_bit_vector = encrypted_nonce_bit_vector ^ ks_bits; + + // compute real parity bits on the fly + parity_bit_vector ^= decrypted_nonce_bit_vector; + + // update state + state_p--; + state_p[0].value = fb_bits ^ decrypted_nonce_bit_vector; + + // update crypto1 subfunctions + bitslice_value_t f20a_1, f20b_1, f20b_2, f20a_2, f20b_3; + f20a_2 = f20a(state_p[47-33].value, state_p[47-35].value, state_p[47-37].value, state_p[47-39].value); + f20b_3 = f20b(state_p[47-41].value, state_p[47-43].value, state_p[47-45].value, state_p[47-47].value); + if (ks_idx > KEYSTREAM_SIZE - 8) { + f20a_1 = f20a(state_p[47- 9].value, state_p[47-11].value, state_p[47-13].value, state_p[47-15].value); + f20b_1 = f20b(state_p[47-17].value, state_p[47-19].value, state_p[47-21].value, state_p[47-23].value); + f20b_2 = f20b(state_p[47-25].value, state_p[47-27].value, state_p[47-29].value, state_p[47-31].value); + crypto1_bs_f20b_2[KEYSTREAM_SIZE - ks_idx] = f20b_2; + crypto1_bs_f20b_3[KEYSTREAM_SIZE - ks_idx] = f20b_3; + } else if (ks_idx > KEYSTREAM_SIZE - 16) { + f20a_1 = f20a(state_p[47- 9].value, state_p[47-11].value, state_p[47-13].value, state_p[47-15].value); + f20b_1 = crypto1_bs_f20b_2[KEYSTREAM_SIZE - ks_idx - 8]; + f20b_2 = f20b(state_p[47-25].value, state_p[47-27].value, state_p[47-29].value, state_p[47-31].value); + crypto1_bs_f20b_2[KEYSTREAM_SIZE - ks_idx] = f20b_2; + } else if (ks_idx > KEYSTREAM_SIZE - 24){ + f20a_1 = f20a(state_p[47- 9].value, state_p[47-11].value, state_p[47-13].value, state_p[47-15].value); + f20b_1 = crypto1_bs_f20b_2[KEYSTREAM_SIZE - ks_idx - 8]; + f20b_2 = crypto1_bs_f20b_3[KEYSTREAM_SIZE - ks_idx - 16]; + } else { + f20a_1 = f20a(state_p[47- 9].value, state_p[47-11].value, state_p[47-13].value, state_p[47-15].value); + f20b_1 = f20b(state_p[47-17].value, state_p[47-19].value, state_p[47-21].value, state_p[47-23].value); + f20b_2 = f20b(state_p[47-25].value, state_p[47-27].value, state_p[47-29].value, state_p[47-31].value); + } + // update keystream bit + ks_bits = f20c(f20a_1, f20b_1, f20b_2, f20a_2, f20b_3); + + // for each completed byte: + if ((ks_idx & 0x07) == 0) { + // get encrypted parity bits + const bitslice_value_t encrypted_parity_bit_vector = bitsliced_encrypted_parity_bits[tests][parity_bit_idx++].value; + + // decrypt parity bits + const bitslice_value_t decrypted_parity_bit_vector = encrypted_parity_bit_vector ^ ks_bits; + + // compare actual parity bits with decrypted parity bits and take count in results vector + results.value &= ~parity_bit_vector ^ decrypted_parity_bit_vector; + + // make sure we still have a match in our set + // if(memcmp(&results, &bs_zeroes, sizeof(bitslice_t)) == 0){ + + // this is much faster on my gcc, because somehow a memcmp needlessly spills/fills all the xmm registers to/from the stack - ??? + // the short-circuiting also helps + if(results.bytes64[0] == 0 +#if MAX_BITSLICES > 64 + && results.bytes64[1] == 0 +#endif +#if MAX_BITSLICES > 128 + && results.bytes64[2] == 0 + && results.bytes64[3] == 0 +#endif + ) { +#if defined (DEBUG_BRUTE_FORCE) + if (elimination_step < MAX_ELIMINATION_STEP) { + keys_eliminated[elimination_step] += MAX_BITSLICES; + } +#endif +#ifdef DEBUG_KEY_ELIMINATION + if (known_target_key != -1 && bucket_contains_test_key[block_idx] && *p_odd == test_state[ODD_STATE]) { + printf("Known target key eliminated in brute_force.\n"); + printf("block_idx = %d/%d, nonce = %d/%d\n", block_idx, bitsliced_blocks, tests, nonces_to_bruteforce); + } +#endif + goto stop_tests; + } + // prepare for next nonce byte +#if defined (DEBUG_BRUTE_FORCE) + elimination_step++; +#endif + parity_bit_vector = bs_zeroes.value; + } + // update feedback bit vector + if (ks_idx != 0) { + fb_bits = + (state_p[47- 0].value ^ state_p[47- 5].value ^ state_p[47- 9].value ^ + state_p[47-10].value ^ state_p[47-12].value ^ state_p[47-14].value ^ + state_p[47-15].value ^ state_p[47-17].value ^ state_p[47-19].value ^ + state_p[47-24].value ^ state_p[47-25].value ^ state_p[47-27].value ^ + state_p[47-29].value ^ state_p[47-35].value ^ state_p[47-39].value ^ + state_p[47-41].value ^ state_p[47-42].value ^ state_p[47-43].value); + } + // remember feedback and keystream vectors for later use + uint8_t bit = KEYSTREAM_SIZE - ks_idx; + if (bit <= next_common_bits) { // if needed and not yet stored + fbb[bit] = fb_bits; + ksb[bit] = ks_bits; + par[bit] = parity_bit_vector; + } + } + // prepare for next nonce. Revert to initial state + state_p = &states[KEYSTREAM_SIZE]; + } + + // all nonce tests were successful: we've found a possible key in this block! + uint32_t *p_even_test = p_even; + for (uint32_t results_word = 0; results_word < MAX_BITSLICES / 64; ++results_word) { + uint64_t results64 = results.bytes64[results_word]; + for (uint32_t results_bit = 0; results_bit < 64; results_bit++) { + if (results64 & 0x01) { + if (verify_key(cuid, nonces, best_first_bytes, *p_odd, *p_even_test)) { + struct Crypto1State pcs; + pcs.odd = *p_odd; + pcs.even = *p_even_test; + lfsr_rollback_byte(&pcs, (cuid >> 24) ^ best_first_bytes[0], true); + crypto1_get_lfsr(&pcs, &key); + bucket_states_tested += 64 * results_word + results_bit; + goto out; + } +#ifdef DEBUG_KEY_ELIMINATION + if (known_target_key != -1 && *p_even_test == test_state[EVEN_STATE] && *p_odd == test_state[ODD_STATE]) { + printf("Known target key eliminated in brute_force verification.\n"); + printf("block_idx = %d/%d\n", block_idx, bitsliced_blocks); + } +#endif + } +#ifdef DEBUG_KEY_ELIMINATION + if (known_target_key != -1 && *p_even_test == test_state[EVEN_STATE] && *p_odd == test_state[ODD_STATE]) { + printf("Known target key eliminated in brute_force (results_bit == 0).\n"); + printf("block_idx = %d/%d\n", block_idx, bitsliced_blocks); + } +#endif + results64 >>= 1; + p_even_test++; + if (p_even_test == p_even_end) { + goto stop_tests; + } + } + } +stop_tests: +#if defined (DEBUG_BRUTE_FORCE) + elimination_step = 0; +#endif + bucket_states_tested += bucket_size[block_idx]; + // prepare to set new states + state_p = &states[KEYSTREAM_SIZE]; + continue; + } + } +out: + for(uint32_t block_idx = 0; block_idx < bitsliced_blocks; ++block_idx){ + free_bitslice(bitsliced_even_states[block_idx]); + } + free(bitsliced_even_states); + free_bitslice(bitsliced_even_feedback); + __sync_fetch_and_add(num_keys_tested, bucket_states_tested); + +#if defined (DEBUG_BRUTE_FORCE) + for (uint32_t i = 0; i < MAX_ELIMINATION_STEP; i++) { + printf("Eliminated after %2u test_bytes: %5.2f%%\n", i+1, (float)keys_eliminated[i] / bucket_states_tested * 100); + } +#endif + return key; +} + + + +#ifndef __MMX__ + +// pointers to functions: +crack_states_bitsliced_t *crack_states_bitsliced_function_p = &crack_states_bitsliced_dispatch; +bitslice_test_nonces_t *bitslice_test_nonces_function_p = &bitslice_test_nonces_dispatch; + +// determine the available instruction set at runtime and call the correct function +const uint64_t crack_states_bitsliced_dispatch(uint32_t cuid, uint8_t *best_first_bytes, statelist_t *p, uint32_t *keys_found, uint64_t *num_keys_tested, uint32_t nonces_to_bruteforce, uint8_t *bf_test_nonce_2nd_byte, noncelist_t *nonces) { +#if defined (__i386__) || defined (__x86_64__) + #if !defined(__APPLE__) || (defined(__APPLE__) && (__clang_major__ > 8)) + #if (__GNUC__ >= 5) && (__GNUC__ > 5 || __GNUC_MINOR__ > 2) + if (__builtin_cpu_supports("avx512f")) crack_states_bitsliced_function_p = &crack_states_bitsliced_AVX512; + else if (__builtin_cpu_supports("avx2")) crack_states_bitsliced_function_p = &crack_states_bitsliced_AVX2; + #else + if (__builtin_cpu_supports("avx2")) crack_states_bitsliced_function_p = &crack_states_bitsliced_AVX2; + #endif + else if (__builtin_cpu_supports("avx")) crack_states_bitsliced_function_p = &crack_states_bitsliced_AVX; + else if (__builtin_cpu_supports("sse2")) crack_states_bitsliced_function_p = &crack_states_bitsliced_SSE2; + else if (__builtin_cpu_supports("mmx")) crack_states_bitsliced_function_p = &crack_states_bitsliced_MMX; + else + #endif +#endif + crack_states_bitsliced_function_p = &crack_states_bitsliced_NOSIMD; + + // call the most optimized function for this CPU + return (*crack_states_bitsliced_function_p)(cuid, best_first_bytes, p, keys_found, num_keys_tested, nonces_to_bruteforce, bf_test_nonce_2nd_byte, nonces); +} + +void bitslice_test_nonces_dispatch(uint32_t nonces_to_bruteforce, uint32_t *bf_test_nonce, uint8_t *bf_test_nonce_par) { +#if defined (__i386__) || defined (__x86_64__) + #if !defined(__APPLE__) || (defined(__APPLE__) && (__clang_major__ > 8)) + #if (__GNUC__ >= 5) && (__GNUC__ > 5 || __GNUC_MINOR__ > 2) + if (__builtin_cpu_supports("avx512f")) bitslice_test_nonces_function_p = &bitslice_test_nonces_AVX512; + else if (__builtin_cpu_supports("avx2")) bitslice_test_nonces_function_p = &bitslice_test_nonces_AVX2; + #else + if (__builtin_cpu_supports("avx2")) bitslice_test_nonces_function_p = &bitslice_test_nonces_AVX2; + #endif + else if (__builtin_cpu_supports("avx")) bitslice_test_nonces_function_p = &bitslice_test_nonces_AVX; + else if (__builtin_cpu_supports("sse2")) bitslice_test_nonces_function_p = &bitslice_test_nonces_SSE2; + else if (__builtin_cpu_supports("mmx")) bitslice_test_nonces_function_p = &bitslice_test_nonces_MMX; + else + #endif +#endif + bitslice_test_nonces_function_p = &bitslice_test_nonces_NOSIMD; + + // call the most optimized function for this CPU + (*bitslice_test_nonces_function_p)(nonces_to_bruteforce, bf_test_nonce, bf_test_nonce_par); +} + +// Entries to dispatched function calls +const uint64_t crack_states_bitsliced(uint32_t cuid, uint8_t *best_first_bytes, statelist_t *p, uint32_t *keys_found, uint64_t *num_keys_tested, uint32_t nonces_to_bruteforce, uint8_t *bf_test_nonce_2nd_byte, noncelist_t *nonces) { + return (*crack_states_bitsliced_function_p)(cuid, best_first_bytes, p, keys_found, num_keys_tested, nonces_to_bruteforce, bf_test_nonce_2nd_byte, nonces); +} + +void bitslice_test_nonces(uint32_t nonces_to_bruteforce, uint32_t *bf_test_nonce, uint8_t *bf_test_nonce_par) { + (*bitslice_test_nonces_function_p)(nonces_to_bruteforce, bf_test_nonce, bf_test_nonce_par); +} + +#endif diff --git a/client/hardnested/hardnested_bf_core.h b/client/hardnested/hardnested_bf_core.h new file mode 100644 index 000000000..7a445993e --- /dev/null +++ b/client/hardnested/hardnested_bf_core.h @@ -0,0 +1,58 @@ +//----------------------------------------------------------------------------- +// Copyright (C) 2016, 2017 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 +//----------------------------------------------------------------------------- +// +// brute forcing is based on @aczids bitsliced brute forcer +// https://github.com/aczid/crypto1_bs with some modifications. Mainly: +// - don't rollback. Start with 2nd byte of nonce instead +// - reuse results of filter subfunctions +// - reuse results of previous nonces if some first bits are identical +// +//----------------------------------------------------------------------------- +// aczid's Copyright notice: +// +// Bit-sliced Crypto-1 brute-forcing implementation +// Builds on the data structures returned by CraptEV1 craptev1_get_space(nonces, threshold, uid) +/* +Copyright (c) 2015-2016 Aram Verstegen + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#ifndef HARDNESTED_BF_CORE_H__ +#define HARDNESTED_BF_CORE_H__ + +#include "hardnested_bruteforce.h" // statelist_t + +extern const uint64_t crack_states_bitsliced(uint32_t cuid, uint8_t *best_first_bytes, statelist_t *p, uint32_t *keys_found, uint64_t *num_keys_tested, uint32_t nonces_to_bruteforce, uint8_t *bf_test_nonces_2nd_byte, noncelist_t *nonces); +extern void bitslice_test_nonces(uint32_t nonces_to_bruteforce, uint32_t *bf_test_nonces, uint8_t *bf_test_nonce_par); + +#endif diff --git a/client/hardnested/hardnested_bitarray_core.c b/client/hardnested/hardnested_bitarray_core.c new file mode 100644 index 000000000..5615d0060 --- /dev/null +++ b/client/hardnested/hardnested_bitarray_core.c @@ -0,0 +1,650 @@ +//----------------------------------------------------------------------------- +// Copyright (C) 2016, 2017 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.ch b +//----------------------------------------------------------------------------- +// 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 +//----------------------------------------------------------------------------- +// some helper functions which can benefit from SIMD instructions or other special instructions +// + +#include "hardnested_bitarray_core.h" + +#include +#include +#include +#ifndef __APPLE__ +#include +#endif + +// this needs to be compiled several times for each instruction set. +// For each instruction set, define a dedicated function name: +#if defined (__AVX512F__) +#define MALLOC_BITARRAY malloc_bitarray_AVX512 +#define FREE_BITARRAY free_bitarray_AVX512 +#define BITCOUNT bitcount_AVX512 +#define COUNT_STATES count_states_AVX512 +#define BITARRAY_AND bitarray_AND_AVX512 +#define BITARRAY_LOW20_AND bitarray_low20_AND_AVX512 +#define COUNT_BITARRAY_AND count_bitarray_AND_AVX512 +#define COUNT_BITARRAY_LOW20_AND count_bitarray_low20_AND_AVX512 +#define BITARRAY_AND4 bitarray_AND4_AVX512 +#define BITARRAY_OR bitarray_OR_AVX512 +#define COUNT_BITARRAY_AND2 count_bitarray_AND2_AVX512 +#define COUNT_BITARRAY_AND3 count_bitarray_AND3_AVX512 +#define COUNT_BITARRAY_AND4 count_bitarray_AND4_AVX512 +#elif defined (__AVX2__) +#define MALLOC_BITARRAY malloc_bitarray_AVX2 +#define FREE_BITARRAY free_bitarray_AVX2 +#define BITCOUNT bitcount_AVX2 +#define COUNT_STATES count_states_AVX2 +#define BITARRAY_AND bitarray_AND_AVX2 +#define BITARRAY_LOW20_AND bitarray_low20_AND_AVX2 +#define COUNT_BITARRAY_AND count_bitarray_AND_AVX2 +#define COUNT_BITARRAY_LOW20_AND count_bitarray_low20_AND_AVX2 +#define BITARRAY_AND4 bitarray_AND4_AVX2 +#define BITARRAY_OR bitarray_OR_AVX2 +#define COUNT_BITARRAY_AND2 count_bitarray_AND2_AVX2 +#define COUNT_BITARRAY_AND3 count_bitarray_AND3_AVX2 +#define COUNT_BITARRAY_AND4 count_bitarray_AND4_AVX2 +#elif defined (__AVX__) +#define MALLOC_BITARRAY malloc_bitarray_AVX +#define FREE_BITARRAY free_bitarray_AVX +#define BITCOUNT bitcount_AVX +#define COUNT_STATES count_states_AVX +#define BITARRAY_AND bitarray_AND_AVX +#define BITARRAY_LOW20_AND bitarray_low20_AND_AVX +#define COUNT_BITARRAY_AND count_bitarray_AND_AVX +#define COUNT_BITARRAY_LOW20_AND count_bitarray_low20_AND_AVX +#define BITARRAY_AND4 bitarray_AND4_AVX +#define BITARRAY_OR bitarray_OR_AVX +#define COUNT_BITARRAY_AND2 count_bitarray_AND2_AVX +#define COUNT_BITARRAY_AND3 count_bitarray_AND3_AVX +#define COUNT_BITARRAY_AND4 count_bitarray_AND4_AVX +#elif defined (__SSE2__) +#define MALLOC_BITARRAY malloc_bitarray_SSE2 +#define FREE_BITARRAY free_bitarray_SSE2 +#define BITCOUNT bitcount_SSE2 +#define COUNT_STATES count_states_SSE2 +#define BITARRAY_AND bitarray_AND_SSE2 +#define BITARRAY_LOW20_AND bitarray_low20_AND_SSE2 +#define COUNT_BITARRAY_AND count_bitarray_AND_SSE2 +#define COUNT_BITARRAY_LOW20_AND count_bitarray_low20_AND_SSE2 +#define BITARRAY_AND4 bitarray_AND4_SSE2 +#define BITARRAY_OR bitarray_OR_SSE2 +#define COUNT_BITARRAY_AND2 count_bitarray_AND2_SSE2 +#define COUNT_BITARRAY_AND3 count_bitarray_AND3_SSE2 +#define COUNT_BITARRAY_AND4 count_bitarray_AND4_SSE2 +#elif defined (__MMX__) +#define MALLOC_BITARRAY malloc_bitarray_MMX +#define FREE_BITARRAY free_bitarray_MMX +#define BITCOUNT bitcount_MMX +#define COUNT_STATES count_states_MMX +#define BITARRAY_AND bitarray_AND_MMX +#define BITARRAY_LOW20_AND bitarray_low20_AND_MMX +#define COUNT_BITARRAY_AND count_bitarray_AND_MMX +#define COUNT_BITARRAY_LOW20_AND count_bitarray_low20_AND_MMX +#define BITARRAY_AND4 bitarray_AND4_MMX +#define BITARRAY_OR bitarray_OR_MMX +#define COUNT_BITARRAY_AND2 count_bitarray_AND2_MMX +#define COUNT_BITARRAY_AND3 count_bitarray_AND3_MMX +#define COUNT_BITARRAY_AND4 count_bitarray_AND4_MMX +#else +#define MALLOC_BITARRAY malloc_bitarray_NOSIMD +#define FREE_BITARRAY free_bitarray_NOSIMD +#define BITCOUNT bitcount_NOSIMD +#define COUNT_STATES count_states_NOSIMD +#define BITARRAY_AND bitarray_AND_NOSIMD +#define BITARRAY_LOW20_AND bitarray_low20_AND_NOSIMD +#define COUNT_BITARRAY_AND count_bitarray_AND_NOSIMD +#define COUNT_BITARRAY_LOW20_AND count_bitarray_low20_AND_NOSIMD +#define BITARRAY_AND4 bitarray_AND4_NOSIMD +#define BITARRAY_OR bitarray_OR_NOSIMD +#define COUNT_BITARRAY_AND2 count_bitarray_AND2_NOSIMD +#define COUNT_BITARRAY_AND3 count_bitarray_AND3_NOSIMD +#define COUNT_BITARRAY_AND4 count_bitarray_AND4_NOSIMD +#endif + + +// typedefs and declaration of functions: +typedef uint32_t* malloc_bitarray_t(uint32_t); +malloc_bitarray_t malloc_bitarray_AVX512, malloc_bitarray_AVX2, malloc_bitarray_AVX, malloc_bitarray_SSE2, malloc_bitarray_MMX, malloc_bitarray_NOSIMD, malloc_bitarray_dispatch; +typedef void free_bitarray_t(uint32_t*); +free_bitarray_t free_bitarray_AVX512, free_bitarray_AVX2, free_bitarray_AVX, free_bitarray_SSE2, free_bitarray_MMX, free_bitarray_NOSIMD, free_bitarray_dispatch; +typedef uint32_t bitcount_t(uint32_t); +bitcount_t bitcount_AVX512, bitcount_AVX2, bitcount_AVX, bitcount_SSE2, bitcount_MMX, bitcount_NOSIMD, bitcount_dispatch; +typedef uint32_t count_states_t(uint32_t*); +count_states_t count_states_AVX512, count_states_AVX2, count_states_AVX, count_states_SSE2, count_states_MMX, count_states_NOSIMD, count_states_dispatch; +typedef void bitarray_AND_t(uint32_t[], uint32_t[]); +bitarray_AND_t bitarray_AND_AVX512, bitarray_AND_AVX2, bitarray_AND_AVX, bitarray_AND_SSE2, bitarray_AND_MMX, bitarray_AND_NOSIMD, bitarray_AND_dispatch; +typedef void bitarray_low20_AND_t(uint32_t*, uint32_t*); +bitarray_low20_AND_t bitarray_low20_AND_AVX512, bitarray_low20_AND_AVX2, bitarray_low20_AND_AVX, bitarray_low20_AND_SSE2, bitarray_low20_AND_MMX, bitarray_low20_AND_NOSIMD, bitarray_low20_AND_dispatch; +typedef uint32_t count_bitarray_AND_t(uint32_t*, uint32_t*); +count_bitarray_AND_t count_bitarray_AND_AVX512, count_bitarray_AND_AVX2, count_bitarray_AND_AVX, count_bitarray_AND_SSE2, count_bitarray_AND_MMX, count_bitarray_AND_NOSIMD, count_bitarray_AND_dispatch; +typedef uint32_t count_bitarray_low20_AND_t(uint32_t*, uint32_t*); +count_bitarray_low20_AND_t count_bitarray_low20_AND_AVX512, count_bitarray_low20_AND_AVX2, count_bitarray_low20_AND_AVX, count_bitarray_low20_AND_SSE2, count_bitarray_low20_AND_MMX, count_bitarray_low20_AND_NOSIMD, count_bitarray_low20_AND_dispatch; +typedef void bitarray_AND4_t(uint32_t*, uint32_t*, uint32_t*, uint32_t*); +bitarray_AND4_t bitarray_AND4_AVX512, bitarray_AND4_AVX2, bitarray_AND4_AVX, bitarray_AND4_SSE2, bitarray_AND4_MMX, bitarray_AND4_NOSIMD, bitarray_AND4_dispatch; +typedef void bitarray_OR_t(uint32_t[], uint32_t[]); +bitarray_OR_t bitarray_OR_AVX512, bitarray_OR_AVX2, bitarray_OR_AVX, bitarray_OR_SSE2, bitarray_OR_MMX, bitarray_OR_NOSIMD, bitarray_OR_dispatch; +typedef uint32_t count_bitarray_AND2_t(uint32_t*, uint32_t*); +count_bitarray_AND2_t count_bitarray_AND2_AVX512, count_bitarray_AND2_AVX2, count_bitarray_AND2_AVX, count_bitarray_AND2_SSE2, count_bitarray_AND2_MMX, count_bitarray_AND2_NOSIMD, count_bitarray_AND2_dispatch; +typedef uint32_t count_bitarray_AND3_t(uint32_t*, uint32_t*, uint32_t*); +count_bitarray_AND3_t count_bitarray_AND3_AVX512, count_bitarray_AND3_AVX2, count_bitarray_AND3_AVX, count_bitarray_AND3_SSE2, count_bitarray_AND3_MMX, count_bitarray_AND3_NOSIMD, count_bitarray_AND3_dispatch; +typedef uint32_t count_bitarray_AND4_t(uint32_t*, uint32_t*, uint32_t*, uint32_t*); +count_bitarray_AND4_t count_bitarray_AND4_AVX512, count_bitarray_AND4_AVX2, count_bitarray_AND4_AVX, count_bitarray_AND4_SSE2, count_bitarray_AND4_MMX, count_bitarray_AND4_NOSIMD, count_bitarray_AND4_dispatch; + + +inline uint32_t *MALLOC_BITARRAY(uint32_t x) +{ +#if defined (_WIN32) + return __builtin_assume_aligned(_aligned_malloc((x), __BIGGEST_ALIGNMENT__), __BIGGEST_ALIGNMENT__); +#elif defined (__APPLE__) + uint32_t *allocated_memory; + if (posix_memalign((void**)&allocated_memory, __BIGGEST_ALIGNMENT__, x)) { + return NULL; + } else { + return __builtin_assume_aligned(allocated_memory, __BIGGEST_ALIGNMENT__); + } +#else + return __builtin_assume_aligned(memalign(__BIGGEST_ALIGNMENT__, (x)), __BIGGEST_ALIGNMENT__); +#endif +} + + +inline void FREE_BITARRAY(uint32_t *x) +{ +#ifdef _WIN32 + _aligned_free(x); +#else + free(x); +#endif +} + + +inline uint32_t BITCOUNT(uint32_t a) +{ + return __builtin_popcountl(a); +} + + +inline uint32_t COUNT_STATES(uint32_t *A) +{ + uint32_t count = 0; + for (uint32_t i = 0; i < (1<<19); i++) { + count += BITCOUNT(A[i]); + } + return count; +} + + +inline void BITARRAY_AND(uint32_t *restrict A, uint32_t *restrict B) +{ + A = __builtin_assume_aligned(A, __BIGGEST_ALIGNMENT__); + B = __builtin_assume_aligned(B, __BIGGEST_ALIGNMENT__); + for (uint32_t i = 0; i < (1<<19); i++) { + A[i] &= B[i]; + } +} + + +inline void BITARRAY_LOW20_AND(uint32_t *restrict A, uint32_t *restrict B) +{ + uint16_t *a = (uint16_t *)__builtin_assume_aligned(A, __BIGGEST_ALIGNMENT__); + uint16_t *b = (uint16_t *)__builtin_assume_aligned(B, __BIGGEST_ALIGNMENT__); + + for (uint32_t i = 0; i < (1<<20); i++) { + if (!b[i]) { + a[i] = 0; + } + } +} + + +inline uint32_t COUNT_BITARRAY_AND(uint32_t *restrict A, uint32_t *restrict B) +{ + A = __builtin_assume_aligned(A, __BIGGEST_ALIGNMENT__); + B = __builtin_assume_aligned(B, __BIGGEST_ALIGNMENT__); + uint32_t count = 0; + for (uint32_t i = 0; i < (1<<19); i++) { + A[i] &= B[i]; + count += BITCOUNT(A[i]); + } + return count; +} + + +inline uint32_t COUNT_BITARRAY_LOW20_AND(uint32_t *restrict A, uint32_t *restrict B) +{ + uint16_t *a = (uint16_t *)__builtin_assume_aligned(A, __BIGGEST_ALIGNMENT__); + uint16_t *b = (uint16_t *)__builtin_assume_aligned(B, __BIGGEST_ALIGNMENT__); + uint32_t count = 0; + + for (uint32_t i = 0; i < (1<<20); i++) { + if (!b[i]) { + a[i] = 0; + } + count += BITCOUNT(a[i]); + } + return count; +} + + +inline void BITARRAY_AND4(uint32_t *restrict A, uint32_t *restrict B, uint32_t *restrict C, uint32_t *restrict D) +{ + A = __builtin_assume_aligned(A, __BIGGEST_ALIGNMENT__); + B = __builtin_assume_aligned(B, __BIGGEST_ALIGNMENT__); + C = __builtin_assume_aligned(C, __BIGGEST_ALIGNMENT__); + D = __builtin_assume_aligned(D, __BIGGEST_ALIGNMENT__); + for (uint32_t i = 0; i < (1<<19); i++) { + A[i] = B[i] & C[i] & D[i]; + } +} + + +inline void BITARRAY_OR(uint32_t *restrict A, uint32_t *restrict B) +{ + A = __builtin_assume_aligned(A, __BIGGEST_ALIGNMENT__); + B = __builtin_assume_aligned(B, __BIGGEST_ALIGNMENT__); + for (uint32_t i = 0; i < (1<<19); i++) { + A[i] |= B[i]; + } +} + + +inline uint32_t COUNT_BITARRAY_AND2(uint32_t *restrict A, uint32_t *restrict B) +{ + A = __builtin_assume_aligned(A, __BIGGEST_ALIGNMENT__); + B = __builtin_assume_aligned(B, __BIGGEST_ALIGNMENT__); + uint32_t count = 0; + for (uint32_t i = 0; i < (1<<19); i++) { + count += BITCOUNT(A[i] & B[i]); + } + return count; +} + + +inline uint32_t COUNT_BITARRAY_AND3(uint32_t *restrict A, uint32_t *restrict B, uint32_t *restrict C) +{ + A = __builtin_assume_aligned(A, __BIGGEST_ALIGNMENT__); + B = __builtin_assume_aligned(B, __BIGGEST_ALIGNMENT__); + C = __builtin_assume_aligned(C, __BIGGEST_ALIGNMENT__); + uint32_t count = 0; + for (uint32_t i = 0; i < (1<<19); i++) { + count += BITCOUNT(A[i] & B[i] & C[i]); + } + return count; +} + + +inline uint32_t COUNT_BITARRAY_AND4(uint32_t *restrict A, uint32_t *restrict B, uint32_t *restrict C, uint32_t *restrict D) +{ + A = __builtin_assume_aligned(A, __BIGGEST_ALIGNMENT__); + B = __builtin_assume_aligned(B, __BIGGEST_ALIGNMENT__); + C = __builtin_assume_aligned(C, __BIGGEST_ALIGNMENT__); + D = __builtin_assume_aligned(D, __BIGGEST_ALIGNMENT__); + uint32_t count = 0; + for (uint32_t i = 0; i < (1<<19); i++) { + count += BITCOUNT(A[i] & B[i] & C[i] & D[i]); + } + return count; +} + + +#ifndef __MMX__ + +// pointers to functions: +malloc_bitarray_t *malloc_bitarray_function_p = &malloc_bitarray_dispatch; +free_bitarray_t *free_bitarray_function_p = &free_bitarray_dispatch; +bitcount_t *bitcount_function_p = &bitcount_dispatch; +count_states_t *count_states_function_p = &count_states_dispatch; +bitarray_AND_t *bitarray_AND_function_p = &bitarray_AND_dispatch; +bitarray_low20_AND_t *bitarray_low20_AND_function_p = &bitarray_low20_AND_dispatch; +count_bitarray_AND_t *count_bitarray_AND_function_p = &count_bitarray_AND_dispatch; +count_bitarray_low20_AND_t *count_bitarray_low20_AND_function_p = &count_bitarray_low20_AND_dispatch; +bitarray_AND4_t *bitarray_AND4_function_p = &bitarray_AND4_dispatch; +bitarray_OR_t *bitarray_OR_function_p = &bitarray_OR_dispatch; +count_bitarray_AND2_t *count_bitarray_AND2_function_p = &count_bitarray_AND2_dispatch; +count_bitarray_AND3_t *count_bitarray_AND3_function_p = &count_bitarray_AND3_dispatch; +count_bitarray_AND4_t *count_bitarray_AND4_function_p = &count_bitarray_AND4_dispatch; + +// determine the available instruction set at runtime and call the correct function +uint32_t *malloc_bitarray_dispatch(uint32_t x) { +#if defined (__i386__) || defined (__x86_64__) + #if !defined(__APPLE__) || (defined(__APPLE__) && (__clang_major__ > 8)) + #if (__GNUC__ >= 5) && (__GNUC__ > 5 || __GNUC_MINOR__ > 2) + if (__builtin_cpu_supports("avx512f")) malloc_bitarray_function_p = &malloc_bitarray_AVX512; + else if (__builtin_cpu_supports("avx2")) malloc_bitarray_function_p = &malloc_bitarray_AVX2; + #else + if (__builtin_cpu_supports("avx2")) malloc_bitarray_function_p = &malloc_bitarray_AVX2; + #endif + else if (__builtin_cpu_supports("avx")) malloc_bitarray_function_p = &malloc_bitarray_AVX; + else if (__builtin_cpu_supports("sse2")) malloc_bitarray_function_p = &malloc_bitarray_SSE2; + else if (__builtin_cpu_supports("mmx")) malloc_bitarray_function_p = &malloc_bitarray_MMX; + else + #endif +#endif + malloc_bitarray_function_p = &malloc_bitarray_NOSIMD; + + // call the most optimized function for this CPU + return (*malloc_bitarray_function_p)(x); +} + +void free_bitarray_dispatch(uint32_t *x) { +#if defined (__i386__) || defined (__x86_64__) + #if !defined(__APPLE__) || (defined(__APPLE__) && (__clang_major__ > 8)) + #if (__GNUC__ >= 5) && (__GNUC__ > 5 || __GNUC_MINOR__ > 2) + if (__builtin_cpu_supports("avx512f")) free_bitarray_function_p = &free_bitarray_AVX512; + else if (__builtin_cpu_supports("avx2")) free_bitarray_function_p = &free_bitarray_AVX2; + #else + if (__builtin_cpu_supports("avx2")) free_bitarray_function_p = &free_bitarray_AVX2; + #endif + else if (__builtin_cpu_supports("avx")) free_bitarray_function_p = &free_bitarray_AVX; + else if (__builtin_cpu_supports("sse2")) free_bitarray_function_p = &free_bitarray_SSE2; + else if (__builtin_cpu_supports("mmx")) free_bitarray_function_p = &free_bitarray_MMX; + else + #endif +#endif + free_bitarray_function_p = &free_bitarray_NOSIMD; + + // call the most optimized function for this CPU + (*free_bitarray_function_p)(x); +} + +uint32_t bitcount_dispatch(uint32_t a) { +#if defined (__i386__) || defined (__x86_64__) + #if !defined(__APPLE__) || (defined(__APPLE__) && (__clang_major__ > 8)) + #if (__GNUC__ >= 5) && (__GNUC__ > 5 || __GNUC_MINOR__ > 2) + if (__builtin_cpu_supports("avx512f")) bitcount_function_p = &bitcount_AVX512; + else if (__builtin_cpu_supports("avx2")) bitcount_function_p = &bitcount_AVX2; + #else + if (__builtin_cpu_supports("avx2")) bitcount_function_p = &bitcount_AVX2; + #endif + else if (__builtin_cpu_supports("avx")) bitcount_function_p = &bitcount_AVX; + else if (__builtin_cpu_supports("sse2")) bitcount_function_p = &bitcount_SSE2; + else if (__builtin_cpu_supports("mmx")) bitcount_function_p = &bitcount_MMX; + else + #endif +#endif + bitcount_function_p = &bitcount_NOSIMD; + + // call the most optimized function for this CPU + return (*bitcount_function_p)(a); +} + +uint32_t count_states_dispatch(uint32_t *bitarray) { +#if defined (__i386__) || defined (__x86_64__) + #if !defined(__APPLE__) || (defined(__APPLE__) && (__clang_major__ > 8)) + #if (__GNUC__ >= 5) && (__GNUC__ > 5 || __GNUC_MINOR__ > 2) + if (__builtin_cpu_supports("avx512f")) count_states_function_p = &count_states_AVX512; + else if (__builtin_cpu_supports("avx2")) count_states_function_p = &count_states_AVX2; + #else + if (__builtin_cpu_supports("avx2")) count_states_function_p = &count_states_AVX2; + #endif + else if (__builtin_cpu_supports("avx")) count_states_function_p = &count_states_AVX; + else if (__builtin_cpu_supports("sse2")) count_states_function_p = &count_states_SSE2; + else if (__builtin_cpu_supports("mmx")) count_states_function_p = &count_states_MMX; + else + #endif +#endif + count_states_function_p = &count_states_NOSIMD; + + // call the most optimized function for this CPU + return (*count_states_function_p)(bitarray); +} + +void bitarray_AND_dispatch(uint32_t *A, uint32_t *B) { +#if defined (__i386__) || defined (__x86_64__) + #if !defined(__APPLE__) || (defined(__APPLE__) && (__clang_major__ > 8)) + #if (__GNUC__ >= 5) && (__GNUC__ > 5 || __GNUC_MINOR__ > 2) + if (__builtin_cpu_supports("avx512f")) bitarray_AND_function_p = &bitarray_AND_AVX512; + else if (__builtin_cpu_supports("avx2")) bitarray_AND_function_p = &bitarray_AND_AVX2; + #else + if (__builtin_cpu_supports("avx2")) bitarray_AND_function_p = &bitarray_AND_AVX2; + #endif + else if (__builtin_cpu_supports("avx")) bitarray_AND_function_p = &bitarray_AND_AVX; + else if (__builtin_cpu_supports("sse2")) bitarray_AND_function_p = &bitarray_AND_SSE2; + else if (__builtin_cpu_supports("mmx")) bitarray_AND_function_p = &bitarray_AND_MMX; + else + #endif +#endif + bitarray_AND_function_p = &bitarray_AND_NOSIMD; + + // call the most optimized function for this CPU + (*bitarray_AND_function_p)(A,B); +} + +void bitarray_low20_AND_dispatch(uint32_t *A, uint32_t *B) { +#if defined (__i386__) || defined (__x86_64__) + #if !defined(__APPLE__) || (defined(__APPLE__) && (__clang_major__ > 8)) + #if (__GNUC__ >= 5) && (__GNUC__ > 5 || __GNUC_MINOR__ > 2) + if (__builtin_cpu_supports("avx512f")) bitarray_low20_AND_function_p = &bitarray_low20_AND_AVX512; + else if (__builtin_cpu_supports("avx2")) bitarray_low20_AND_function_p = &bitarray_low20_AND_AVX2; + #else + if (__builtin_cpu_supports("avx2")) bitarray_low20_AND_function_p = &bitarray_low20_AND_AVX2; + #endif + else if (__builtin_cpu_supports("avx")) bitarray_low20_AND_function_p = &bitarray_low20_AND_AVX; + else if (__builtin_cpu_supports("sse2")) bitarray_low20_AND_function_p = &bitarray_low20_AND_SSE2; + else if (__builtin_cpu_supports("mmx")) bitarray_low20_AND_function_p = &bitarray_low20_AND_MMX; + else + #endif +#endif + bitarray_low20_AND_function_p = &bitarray_low20_AND_NOSIMD; + + // call the most optimized function for this CPU + (*bitarray_low20_AND_function_p)(A, B); +} + +uint32_t count_bitarray_AND_dispatch(uint32_t *A, uint32_t *B) { +#if defined (__i386__) || defined (__x86_64__) + #if !defined(__APPLE__) || (defined(__APPLE__) && (__clang_major__ > 8)) + #if (__GNUC__ >= 5) && (__GNUC__ > 5 || __GNUC_MINOR__ > 2) + if (__builtin_cpu_supports("avx512f")) count_bitarray_AND_function_p = &count_bitarray_AND_AVX512; + else if (__builtin_cpu_supports("avx2")) count_bitarray_AND_function_p = &count_bitarray_AND_AVX2; + #else + if (__builtin_cpu_supports("avx2")) count_bitarray_AND_function_p = &count_bitarray_AND_AVX2; + #endif + else if (__builtin_cpu_supports("avx")) count_bitarray_AND_function_p = &count_bitarray_AND_AVX; + else if (__builtin_cpu_supports("sse2")) count_bitarray_AND_function_p = &count_bitarray_AND_SSE2; + else if (__builtin_cpu_supports("mmx")) count_bitarray_AND_function_p = &count_bitarray_AND_MMX; + else + #endif +#endif + count_bitarray_AND_function_p = &count_bitarray_AND_NOSIMD; + + // call the most optimized function for this CPU + return (*count_bitarray_AND_function_p)(A, B); +} + +uint32_t count_bitarray_low20_AND_dispatch(uint32_t *A, uint32_t *B) { +#if defined (__i386__) || defined (__x86_64__) + #if !defined(__APPLE__) || (defined(__APPLE__) && (__clang_major__ > 8)) + #if (__GNUC__ >= 5) && (__GNUC__ > 5 || __GNUC_MINOR__ > 2) + if (__builtin_cpu_supports("avx512f")) count_bitarray_low20_AND_function_p = &count_bitarray_low20_AND_AVX512; + else if (__builtin_cpu_supports("avx2")) count_bitarray_low20_AND_function_p = &count_bitarray_low20_AND_AVX2; + #else + if (__builtin_cpu_supports("avx2")) count_bitarray_low20_AND_function_p = &count_bitarray_low20_AND_AVX2; + #endif + else if (__builtin_cpu_supports("avx")) count_bitarray_low20_AND_function_p = &count_bitarray_low20_AND_AVX; + else if (__builtin_cpu_supports("sse2")) count_bitarray_low20_AND_function_p = &count_bitarray_low20_AND_SSE2; + else if (__builtin_cpu_supports("mmx")) count_bitarray_low20_AND_function_p = &count_bitarray_low20_AND_MMX; + else + #endif +#endif + count_bitarray_low20_AND_function_p = &count_bitarray_low20_AND_NOSIMD; + + // call the most optimized function for this CPU + return (*count_bitarray_low20_AND_function_p)(A, B); +} + +void bitarray_AND4_dispatch(uint32_t *A, uint32_t *B, uint32_t *C, uint32_t *D) { +#if defined (__i386__) || defined (__x86_64__) + #if !defined(__APPLE__) || (defined(__APPLE__) && (__clang_major__ > 8)) + #if (__GNUC__ >= 5) && (__GNUC__ > 5 || __GNUC_MINOR__ > 2) + if (__builtin_cpu_supports("avx512f")) bitarray_AND4_function_p = &bitarray_AND4_AVX512; + else if (__builtin_cpu_supports("avx2")) bitarray_AND4_function_p = &bitarray_AND4_AVX2; + #else + if (__builtin_cpu_supports("avx2")) bitarray_AND4_function_p = &bitarray_AND4_AVX2; + #endif + else if (__builtin_cpu_supports("avx")) bitarray_AND4_function_p = &bitarray_AND4_AVX; + else if (__builtin_cpu_supports("sse2")) bitarray_AND4_function_p = &bitarray_AND4_SSE2; + else if (__builtin_cpu_supports("mmx")) bitarray_AND4_function_p = &bitarray_AND4_MMX; + else + #endif +#endif + bitarray_AND4_function_p = &bitarray_AND4_NOSIMD; + + // call the most optimized function for this CPU + (*bitarray_AND4_function_p)(A, B, C, D); +} + +void bitarray_OR_dispatch(uint32_t *A, uint32_t *B) { +#if defined (__i386__) || defined (__x86_64__) + #if !defined(__APPLE__) || (defined(__APPLE__) && (__clang_major__ > 8)) + #if (__GNUC__ >= 5) && (__GNUC__ > 5 || __GNUC_MINOR__ > 2) + if (__builtin_cpu_supports("avx512f")) bitarray_OR_function_p = &bitarray_OR_AVX512; + else if (__builtin_cpu_supports("avx2")) bitarray_OR_function_p = &bitarray_OR_AVX2; + #else + if (__builtin_cpu_supports("avx2")) bitarray_OR_function_p = &bitarray_OR_AVX2; + #endif + else if (__builtin_cpu_supports("avx")) bitarray_OR_function_p = &bitarray_OR_AVX; + else if (__builtin_cpu_supports("sse2")) bitarray_OR_function_p = &bitarray_OR_SSE2; + else if (__builtin_cpu_supports("mmx")) bitarray_OR_function_p = &bitarray_OR_MMX; + else + #endif +#endif + bitarray_OR_function_p = &bitarray_OR_NOSIMD; + + // call the most optimized function for this CPU + (*bitarray_OR_function_p)(A,B); +} + +uint32_t count_bitarray_AND2_dispatch(uint32_t *A, uint32_t *B) { +#if defined (__i386__) || defined (__x86_64__) + #if !defined(__APPLE__) || (defined(__APPLE__) && (__clang_major__ > 8)) + #if (__GNUC__ >= 5) && (__GNUC__ > 5 || __GNUC_MINOR__ > 2) + if (__builtin_cpu_supports("avx512f")) count_bitarray_AND2_function_p = &count_bitarray_AND2_AVX512; + else if (__builtin_cpu_supports("avx2")) count_bitarray_AND2_function_p = &count_bitarray_AND2_AVX2; + #else + if (__builtin_cpu_supports("avx2")) count_bitarray_AND2_function_p = &count_bitarray_AND2_AVX2; + #endif + else if (__builtin_cpu_supports("avx")) count_bitarray_AND2_function_p = &count_bitarray_AND2_AVX; + else if (__builtin_cpu_supports("sse2")) count_bitarray_AND2_function_p = &count_bitarray_AND2_SSE2; + else if (__builtin_cpu_supports("mmx")) count_bitarray_AND2_function_p = &count_bitarray_AND2_MMX; + else + #endif +#endif + count_bitarray_AND2_function_p = &count_bitarray_AND2_NOSIMD; + + // call the most optimized function for this CPU + return (*count_bitarray_AND2_function_p)(A, B); +} + +uint32_t count_bitarray_AND3_dispatch(uint32_t *A, uint32_t *B, uint32_t *C) { +#if defined (__i386__) || defined (__x86_64__) + #if !defined(__APPLE__) || (defined(__APPLE__) && (__clang_major__ > 8)) + #if (__GNUC__ >= 5) && (__GNUC__ > 5 || __GNUC_MINOR__ > 2) + if (__builtin_cpu_supports("avx512f")) count_bitarray_AND3_function_p = &count_bitarray_AND3_AVX512; + else if (__builtin_cpu_supports("avx2")) count_bitarray_AND3_function_p = &count_bitarray_AND3_AVX2; + #else + if (__builtin_cpu_supports("avx2")) count_bitarray_AND3_function_p = &count_bitarray_AND3_AVX2; + #endif + else if (__builtin_cpu_supports("avx")) count_bitarray_AND3_function_p = &count_bitarray_AND3_AVX; + else if (__builtin_cpu_supports("sse2")) count_bitarray_AND3_function_p = &count_bitarray_AND3_SSE2; + else if (__builtin_cpu_supports("mmx")) count_bitarray_AND3_function_p = &count_bitarray_AND3_MMX; + else + #endif +#endif + count_bitarray_AND3_function_p = &count_bitarray_AND3_NOSIMD; + + // call the most optimized function for this CPU + return (*count_bitarray_AND3_function_p)(A, B, C); +} + +uint32_t count_bitarray_AND4_dispatch(uint32_t *A, uint32_t *B, uint32_t *C, uint32_t *D) { +#if defined (__i386__) || defined (__x86_64__) + #if !defined(__APPLE__) || (defined(__APPLE__) && (__clang_major__ > 8)) + #if (__GNUC__ >= 5) && (__GNUC__ > 5 || __GNUC_MINOR__ > 2) + if (__builtin_cpu_supports("avx512f")) count_bitarray_AND4_function_p = &count_bitarray_AND4_AVX512; + else if (__builtin_cpu_supports("avx2")) count_bitarray_AND4_function_p = &count_bitarray_AND4_AVX2; + #else + if (__builtin_cpu_supports("avx2")) count_bitarray_AND4_function_p = &count_bitarray_AND4_AVX2; + #endif + else if (__builtin_cpu_supports("avx")) count_bitarray_AND4_function_p = &count_bitarray_AND4_AVX; + else if (__builtin_cpu_supports("sse2")) count_bitarray_AND4_function_p = &count_bitarray_AND4_SSE2; + else if (__builtin_cpu_supports("mmx")) count_bitarray_AND4_function_p = &count_bitarray_AND4_MMX; + else + #endif +#endif + count_bitarray_AND4_function_p = &count_bitarray_AND4_NOSIMD; + + // call the most optimized function for this CPU + return (*count_bitarray_AND4_function_p)(A, B, C, D); +} + + +///////////////////////////////////////////////77 +// Entries to dispatched function calls + +uint32_t *malloc_bitarray(uint32_t x) { + return (*malloc_bitarray_function_p)(x); +} + +void free_bitarray(uint32_t *x) { + (*free_bitarray_function_p)(x); +} + +uint32_t bitcount(uint32_t a) { + return (*bitcount_function_p)(a); +} + +uint32_t count_states(uint32_t *bitarray) { + return (*count_states_function_p)(bitarray); +} + +void bitarray_AND(uint32_t *A, uint32_t *B) { + (*bitarray_AND_function_p)(A, B); +} + +void bitarray_low20_AND(uint32_t *A, uint32_t *B) { + (*bitarray_low20_AND_function_p)(A, B); +} + +uint32_t count_bitarray_AND(uint32_t *A, uint32_t *B) { + return (*count_bitarray_AND_function_p)(A, B); +} + +uint32_t count_bitarray_low20_AND(uint32_t *A, uint32_t *B) { + return (*count_bitarray_low20_AND_function_p)(A, B); +} + +void bitarray_AND4(uint32_t *A, uint32_t *B, uint32_t *C, uint32_t *D) { + (*bitarray_AND4_function_p)(A, B, C, D); +} + +void bitarray_OR(uint32_t *A, uint32_t *B) { + (*bitarray_OR_function_p)(A, B); +} + +uint32_t count_bitarray_AND2(uint32_t *A, uint32_t *B) { + return (*count_bitarray_AND2_function_p)(A, B); +} + +uint32_t count_bitarray_AND3(uint32_t *A, uint32_t *B, uint32_t *C) { + return (*count_bitarray_AND3_function_p)(A, B, C); +} + +uint32_t count_bitarray_AND4(uint32_t *A, uint32_t *B, uint32_t *C, uint32_t *D) { + return (*count_bitarray_AND4_function_p)(A, B, C, D); +} + +#endif + diff --git a/client/hardnested/hardnested_bitarray_core.h b/client/hardnested/hardnested_bitarray_core.h new file mode 100644 index 000000000..0d92d6b9a --- /dev/null +++ b/client/hardnested/hardnested_bitarray_core.h @@ -0,0 +1,69 @@ +//----------------------------------------------------------------------------- +// Copyright (C) 2016, 2017 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 +//----------------------------------------------------------------------------- +// +// brute forcing is based on @aczids bitsliced brute forcer +// https://github.com/aczid/crypto1_bs with some modifications. Mainly: +// - don't rollback. Start with 2nd byte of nonce instead +// - reuse results of filter subfunctions +// - reuse results of previous nonces if some first bits are identical +// +//----------------------------------------------------------------------------- +// aczid's Copyright notice: +// +// Bit-sliced Crypto-1 brute-forcing implementation +// Builds on the data structures returned by CraptEV1 craptev1_get_space(nonces, threshold, uid) +/* +Copyright (c) 2015-2016 Aram Verstegen + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#ifndef HARDNESTED_BITARRAY_CORE_H__ +#define HARDNESTED_BITARRAY_CORE_H__ + +#include + +extern uint32_t *malloc_bitarray(uint32_t x); +extern void free_bitarray(uint32_t *x); +extern uint32_t bitcount(uint32_t a); +extern uint32_t count_states(uint32_t *A); +extern void bitarray_AND(uint32_t *A, uint32_t *B); +extern void bitarray_low20_AND(uint32_t *A, uint32_t *B); +extern uint32_t count_bitarray_AND(uint32_t *A, uint32_t *B); +extern uint32_t count_bitarray_low20_AND(uint32_t *A, uint32_t *B); +extern void bitarray_AND4(uint32_t *A, uint32_t *B, uint32_t *C, uint32_t *D); +extern void bitarray_OR(uint32_t *A, uint32_t *B); +extern uint32_t count_bitarray_AND2(uint32_t *A, uint32_t *B); +extern uint32_t count_bitarray_AND3(uint32_t *A, uint32_t *B, uint32_t *C); +extern uint32_t count_bitarray_AND4(uint32_t *A, uint32_t *B, uint32_t *C, uint32_t *D); + +#endif diff --git a/client/hardnested/hardnested_bruteforce.c b/client/hardnested/hardnested_bruteforce.c new file mode 100644 index 000000000..718b7c5d5 --- /dev/null +++ b/client/hardnested/hardnested_bruteforce.c @@ -0,0 +1,472 @@ +//----------------------------------------------------------------------------- +// Copyright (C) 2016, 2017 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 +//----------------------------------------------------------------------------- +// +// brute forcing is based on @aczids bitsliced brute forcer +// https://github.com/aczid/crypto1_bs with some modifications. Mainly: +// - don't rollback. Start with 2nd byte of nonce instead +// - reuse results of filter subfunctions +// - reuse results of previous nonces if some first bits are identical +// +//----------------------------------------------------------------------------- +// aczid's Copyright notice: +// +// Bit-sliced Crypto-1 brute-forcing implementation +// Builds on the data structures returned by CraptEV1 craptev1_get_space(nonces, threshold, uid) +/* +Copyright (c) 2015-2016 Aram Verstegen + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#include "hardnested_bruteforce.h" + +#include +#include +#include +#include +#include +#include +#include "proxmark3.h" +#include "cmdhfmfhard.h" +#include "hardnested_bf_core.h" +#include "ui.h" +#include "util.h" +#include "util_posix.h" +#include "crapto1/crapto1.h" +#include "parity.h" + +#define NUM_BRUTE_FORCE_THREADS (num_CPUs()) +#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 + +// debugging options +#define DEBUG_KEY_ELIMINATION +// #define DEBUG_BRUTE_FORCE + +typedef enum { + EVEN_STATE = 0, + ODD_STATE = 1 +} odd_even_t; + +static uint32_t nonces_to_bruteforce = 0; +static uint32_t bf_test_nonce[256]; +static uint8_t bf_test_nonce_2nd_byte[256]; +static uint8_t bf_test_nonce_par[256]; +static uint32_t bucket_count = 0; +static statelist_t* buckets[128]; +static uint32_t keys_found = 0; +static uint64_t num_keys_tested; + + +uint8_t trailing_zeros(uint8_t byte) +{ + static const uint8_t trailing_zeros_LUT[256] = { + 8, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 + }; + + return trailing_zeros_LUT[byte]; +} + + +bool verify_key(uint32_t cuid, noncelist_t *nonces, uint8_t *best_first_bytes, uint32_t odd, uint32_t even) +{ + struct Crypto1State pcs; + for (uint16_t test_first_byte = 1; test_first_byte < 256; test_first_byte++) { + noncelistentry_t *test_nonce = nonces[best_first_bytes[test_first_byte]].first; + while (test_nonce != NULL) { + pcs.odd = odd; + pcs.even = even; + lfsr_rollback_byte(&pcs, (cuid >> 24) ^ best_first_bytes[0], true); + for (int8_t byte_pos = 3; byte_pos >= 0; byte_pos--) { + uint8_t test_par_enc_bit = (test_nonce->par_enc >> byte_pos) & 0x01; // the encoded parity bit + uint8_t test_byte_enc = (test_nonce->nonce_enc >> (8*byte_pos)) & 0xff; // the encoded nonce byte + uint8_t test_byte_dec = crypto1_byte(&pcs, test_byte_enc /* ^ (cuid >> (8*byte_pos)) */, true) ^ test_byte_enc; // decode the nonce byte + uint8_t ks_par = filter(pcs.odd); // the keystream bit to encode/decode the parity bit + uint8_t test_par_enc2 = ks_par ^ evenparity8(test_byte_dec); // determine the decoded byte's parity and encode it + if (test_par_enc_bit != test_par_enc2) { + return false; + } + } + test_nonce = test_nonce->next; + } + } + return true; +} + + +static void* crack_states_thread(void* x){ + + struct arg { + bool silent; + int thread_ID; + uint32_t cuid; + uint32_t num_acquired_nonces; + uint64_t maximum_states; + noncelist_t *nonces; + uint8_t* best_first_bytes; + } *thread_arg; + + thread_arg = (struct arg *)x; + const int thread_id = thread_arg->thread_ID; + uint32_t current_bucket = thread_id; + while(current_bucket < bucket_count){ + statelist_t *bucket = buckets[current_bucket]; + if(bucket){ +#if defined (DEBUG_BRUTE_FORCE) + printf("Thread %u starts working on bucket %u\n", thread_id, current_bucket); +#endif + const uint64_t key = crack_states_bitsliced(thread_arg->cuid, thread_arg->best_first_bytes, bucket, &keys_found, &num_keys_tested, nonces_to_bruteforce, bf_test_nonce_2nd_byte, thread_arg->nonces); + if(key != -1){ + __sync_fetch_and_add(&keys_found, 1); + char progress_text[80]; + sprintf(progress_text, "Brute force phase completed. Key found: %012" PRIx64, key); + hardnested_print_progress(thread_arg->num_acquired_nonces, progress_text, 0.0, 0); + break; + } else if(keys_found){ + break; + } else { + if (!thread_arg->silent) { + char progress_text[80]; + sprintf(progress_text, "Brute force phase: %6.02f%%", 100.0*(float)num_keys_tested/(float)(thread_arg->maximum_states)); + float remaining_bruteforce = thread_arg->nonces[thread_arg->best_first_bytes[0]].expected_num_brute_force - (float)num_keys_tested/2; + hardnested_print_progress(thread_arg->num_acquired_nonces, progress_text, remaining_bruteforce, 5000); + } + } + } + current_bucket += NUM_BRUTE_FORCE_THREADS; + } + return NULL; +} + + +void prepare_bf_test_nonces(noncelist_t *nonces, uint8_t best_first_byte) +{ + // we do bitsliced brute forcing with best_first_bytes[0] only. + // Extract the corresponding 2nd bytes + noncelistentry_t *test_nonce = nonces[best_first_byte].first; + uint32_t i = 0; + while (test_nonce != NULL) { + bf_test_nonce[i] = test_nonce->nonce_enc; + bf_test_nonce_par[i] = test_nonce->par_enc; + bf_test_nonce_2nd_byte[i] = (test_nonce->nonce_enc >> 16) & 0xff; + test_nonce = test_nonce->next; + i++; + } + nonces_to_bruteforce = i; + + // printf("Nonces to bruteforce: %d\n", nonces_to_bruteforce); + // printf("Common bits of first 4 2nd nonce bytes (before sorting): %u %u %u\n", + // trailing_zeros(bf_test_nonce_2nd_byte[1] ^ bf_test_nonce_2nd_byte[0]), + // trailing_zeros(bf_test_nonce_2nd_byte[2] ^ bf_test_nonce_2nd_byte[1]), + // trailing_zeros(bf_test_nonce_2nd_byte[3] ^ bf_test_nonce_2nd_byte[2])); + + uint8_t best_4[4] = {0}; + int sum_best = -1; + for (uint16_t n1 = 0; n1 < nonces_to_bruteforce; n1++) { + for (uint16_t n2 = 0; n2 < nonces_to_bruteforce; n2++) { + if (n2 != n1) { + for (uint16_t n3 = 0; n3 < nonces_to_bruteforce; n3++) { + if ((n3 != n2 && n3 != n1) || nonces_to_bruteforce < 3 + // && trailing_zeros(bf_test_nonce_2nd_byte[n1] ^ bf_test_nonce_2nd_byte[n2]) + // > trailing_zeros(bf_test_nonce_2nd_byte[n2] ^ bf_test_nonce_2nd_byte[n3]) + ) { + for (uint16_t n4 = 0; n4 < nonces_to_bruteforce; n4++) { + if ((n4 != n3 && n4 != n2 && n4 != n1) || nonces_to_bruteforce < 4 + // && trailing_zeros(bf_test_nonce_2nd_byte[n2] ^ bf_test_nonce_2nd_byte[n3]) + // > trailing_zeros(bf_test_nonce_2nd_byte[n3] ^ bf_test_nonce_2nd_byte[n4]) + ) { + int sum = nonces_to_bruteforce > 1 ? trailing_zeros(bf_test_nonce_2nd_byte[n1] ^ bf_test_nonce_2nd_byte[n2]) : 0.0 + + nonces_to_bruteforce > 2 ? trailing_zeros(bf_test_nonce_2nd_byte[n2] ^ bf_test_nonce_2nd_byte[n3]) : 0.0 + + nonces_to_bruteforce > 3 ? trailing_zeros(bf_test_nonce_2nd_byte[n3] ^ bf_test_nonce_2nd_byte[n4]) : 0.0; + if (sum > sum_best) { + sum_best = sum; + best_4[0] = n1; + best_4[1] = n2; + best_4[2] = n3; + best_4[3] = n4; + } + } + } + } + } + } + } + } + + uint32_t bf_test_nonce_temp[4]; + uint8_t bf_test_nonce_par_temp[4]; + uint8_t bf_test_nonce_2nd_byte_temp[4]; + for (uint8_t i = 0; i < 4 && i < nonces_to_bruteforce; i++) { + bf_test_nonce_temp[i] = bf_test_nonce[best_4[i]]; + + bf_test_nonce_par_temp[i] = bf_test_nonce_par[best_4[i]]; + bf_test_nonce_2nd_byte_temp[i] = bf_test_nonce_2nd_byte[best_4[i]]; + } + for (uint8_t i = 0; i < 4 && i < nonces_to_bruteforce; i++) { + bf_test_nonce[i] = bf_test_nonce_temp[i]; + bf_test_nonce_par[i] = bf_test_nonce_par_temp[i]; + bf_test_nonce_2nd_byte[i] = bf_test_nonce_2nd_byte_temp[i]; + } +} + + +#if defined (WRITE_BENCH_FILE) +static void write_benchfile(statelist_t *candidates) { + + printf("Writing brute force benchmark data..."); + FILE *benchfile = fopen(TEST_BENCH_FILENAME, "wb"); + 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); + printf("done.\n"); +} +#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) +{ +#if defined (WRITE_BENCH_FILE) + write_benchfile(candidates); +#endif + bool silent = (bf_rate != NULL); + + // if (!silent) { + // PrintAndLog("Brute force phase starting."); + // PrintAndLog("Using %u-bit bitslices", MAX_BITSLICES); + // } + + keys_found = 0; + num_keys_tested = 0; + + bitslice_test_nonces(nonces_to_bruteforce, bf_test_nonce, bf_test_nonce_par); + + // count number of states to go + bucket_count = 0; + for (statelist_t *p = candidates; p != NULL; p = p->next) { + if (p->states[ODD_STATE] != NULL && p->states[EVEN_STATE] != NULL) { + buckets[bucket_count] = p; + bucket_count++; + } + } + + uint64_t start_time = msclock(); + // enumerate states using all hardware threads, each thread handles one bucket + // if (!silent) { + // PrintAndLog("Starting %u cracking threads to search %u buckets containing a total of %" PRIu64" states...\n", NUM_BRUTE_FORCE_THREADS, bucket_count, maximum_states); + // printf("Common bits of first 4 2nd nonce bytes: %u %u %u\n", + // trailing_zeros(bf_test_nonce_2nd_byte[1] ^ bf_test_nonce_2nd_byte[0]), + // trailing_zeros(bf_test_nonce_2nd_byte[2] ^ bf_test_nonce_2nd_byte[1]), + // trailing_zeros(bf_test_nonce_2nd_byte[3] ^ bf_test_nonce_2nd_byte[2])); + // } + + pthread_t threads[NUM_BRUTE_FORCE_THREADS]; + struct args { + bool silent; + int thread_ID; + uint32_t cuid; + uint32_t num_acquired_nonces; + uint64_t maximum_states; + noncelist_t *nonces; + uint8_t *best_first_bytes; + } thread_args[NUM_BRUTE_FORCE_THREADS]; + + for(uint32_t i = 0; i < NUM_BRUTE_FORCE_THREADS; i++){ + thread_args[i].thread_ID = i; + thread_args[i].silent = silent; + thread_args[i].cuid = cuid; + thread_args[i].num_acquired_nonces = num_acquired_nonces; + thread_args[i].maximum_states = maximum_states; + thread_args[i].nonces = nonces; + thread_args[i].best_first_bytes = best_first_bytes; + pthread_create(&threads[i], NULL, crack_states_thread, (void*)&thread_args[i]); + } + for(uint32_t i = 0; i < NUM_BRUTE_FORCE_THREADS; i++){ + pthread_join(threads[i], 0); + } + + uint64_t elapsed_time = msclock() - start_time; + + // if (!silent) { + // printf("Brute force completed after testing %" PRIu64" (2^%1.1f) keys in %1.1f seconds at a rate of %1.0f (2^%1.1f) keys per second.\n", + // num_keys_tested, + // log(num_keys_tested) / log(2.0), + // (float)elapsed_time/1000.0, + // (float)num_keys_tested / ((float)elapsed_time / 1000.0), + // log((float)num_keys_tested / ((float)elapsed_time/1000.0)) / log(2.0)); + // } + + if (bf_rate != NULL) { + *bf_rate = (float)num_keys_tested / ((float)elapsed_time / 1000.0); + } + + return (keys_found != 0); +} + + +static bool read_bench_data(statelist_t *test_candidates) { + + size_t bytes_read = 0; + uint32_t temp = 0; + uint32_t num_states = 0; + uint32_t states_read = 0; + + char bench_file_path[strlen(get_my_executable_directory()) + strlen(TEST_BENCH_FILENAME) + 1]; + strcpy(bench_file_path, get_my_executable_directory()); + strcat(bench_file_path, TEST_BENCH_FILENAME); + + FILE *benchfile = fopen(bench_file_path, "rb"); + if (benchfile == NULL) { + return false; + } + bytes_read = fread(&nonces_to_bruteforce, 1, sizeof(nonces_to_bruteforce), benchfile); + if (bytes_read != sizeof(nonces_to_bruteforce)) { + fclose(benchfile); + return false; + } + for (uint16_t i = 0; i < nonces_to_bruteforce && i < 256; i++) { + bytes_read = fread(&bf_test_nonce[i], 1, sizeof(uint32_t), benchfile); + if (bytes_read != sizeof(uint32_t)) { + fclose(benchfile); + return false; + } + bf_test_nonce_2nd_byte[i] = (bf_test_nonce[i] >> 16) & 0xff; + bytes_read = fread(&bf_test_nonce_par[i], 1, sizeof(uint8_t), benchfile); + if (bytes_read != sizeof(uint8_t)) { + fclose(benchfile); + return false; + } + } + bytes_read = fread(&num_states, 1, sizeof(uint32_t), benchfile); + if (bytes_read != sizeof(uint32_t)) { + fclose(benchfile); + return false; + } + for (states_read = 0; states_read < MIN(num_states, TEST_BENCH_SIZE); states_read++) { + bytes_read = fread(test_candidates->states[EVEN_STATE] + states_read, 1, sizeof(uint32_t), benchfile); + if (bytes_read != sizeof(uint32_t)) { + fclose(benchfile); + return false; + } + } + for (uint32_t i = states_read; i < TEST_BENCH_SIZE; i++) { + test_candidates->states[EVEN_STATE][i] = test_candidates->states[EVEN_STATE][i-states_read]; + } + for (uint32_t i = states_read; i < num_states; i++) { + bytes_read = fread(&temp, 1, sizeof(uint32_t), benchfile); + if (bytes_read != sizeof(uint32_t)) { + fclose(benchfile); + return false; + } + } + for (states_read = 0; states_read < MIN(num_states, TEST_BENCH_SIZE); states_read++) { + bytes_read = fread(test_candidates->states[ODD_STATE] + states_read, 1, sizeof(uint32_t), benchfile); + if (bytes_read != sizeof(uint32_t)) { + fclose(benchfile); + return false; + } + } + for (uint32_t i = states_read; i < TEST_BENCH_SIZE; i++) { + test_candidates->states[ODD_STATE][i] = test_candidates->states[ODD_STATE][i-states_read]; + } + + fclose(benchfile); + return true; +} + + +float brute_force_benchmark() +{ + statelist_t test_candidates[NUM_BRUTE_FORCE_THREADS]; + + test_candidates[0].states[ODD_STATE] = malloc((TEST_BENCH_SIZE+1) * sizeof(uint32_t)); + test_candidates[0].states[EVEN_STATE] = malloc((TEST_BENCH_SIZE+1) * sizeof(uint32_t)); + for (uint8_t i = 0; i < NUM_BRUTE_FORCE_THREADS - 1; i++){ + test_candidates[i].next = test_candidates + i + 1; + test_candidates[i+1].states[ODD_STATE] = test_candidates[0].states[ODD_STATE]; + test_candidates[i+1].states[EVEN_STATE] = test_candidates[0].states[EVEN_STATE]; + } + test_candidates[NUM_BRUTE_FORCE_THREADS-1].next = NULL; + + if (!read_bench_data(test_candidates)) { + PrintAndLog("Couldn't read benchmark data. Assuming brute force rate of %1.0f states per second", DEFAULT_BRUTE_FORCE_RATE); + return DEFAULT_BRUTE_FORCE_RATE; + } + + for (uint8_t i = 0; i < NUM_BRUTE_FORCE_THREADS; i++) { + test_candidates[i].len[ODD_STATE] = TEST_BENCH_SIZE; + test_candidates[i].len[EVEN_STATE] = TEST_BENCH_SIZE; + test_candidates[i].states[ODD_STATE][TEST_BENCH_SIZE] = -1; + test_candidates[i].states[EVEN_STATE][TEST_BENCH_SIZE] = -1; + } + + uint64_t maximum_states = TEST_BENCH_SIZE*TEST_BENCH_SIZE*(uint64_t)NUM_BRUTE_FORCE_THREADS; + + float bf_rate; + brute_force_bs(&bf_rate, test_candidates, 0, 0, maximum_states, NULL, 0); + + free(test_candidates[0].states[ODD_STATE]); + free(test_candidates[0].states[EVEN_STATE]); + + return bf_rate; +} + + diff --git a/client/hardnested/hardnested_bruteforce.h b/client/hardnested/hardnested_bruteforce.h new file mode 100644 index 000000000..d4f6348d0 --- /dev/null +++ b/client/hardnested/hardnested_bruteforce.h @@ -0,0 +1,36 @@ +//----------------------------------------------------------------------------- +// Copyright (C) 2016, 2017 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 +//----------------------------------------------------------------------------- + +#ifndef HARDNESTED_BRUTEFORCE_H__ +#define HARDNESTED_BRUTEFORCE_H__ + +#include +#include +#include "cmdhfmfhard.h" + +typedef struct { + uint32_t *states[2]; + uint32_t len[2]; + void* next; +} statelist_t; + +extern void prepare_bf_test_nonces(noncelist_t *nonces, uint8_t best_first_byte); +extern 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); +extern float brute_force_benchmark(); +extern uint8_t trailing_zeros(uint8_t byte); +extern bool verify_key(uint32_t cuid, noncelist_t *nonces, uint8_t *best_first_bytes, uint32_t odd, uint32_t even); + +#endif diff --git a/client/hardnested/hardnested_tables.c b/client/hardnested/hardnested_tables.c new file mode 100644 index 000000000..278ed9596 --- /dev/null +++ b/client/hardnested/hardnested_tables.c @@ -0,0 +1,592 @@ +//----------------------------------------------------------------------------- +// 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. +// +//----------------------------------------------------------------------------- + +#include +#include +#include +#include +#include +#include +#include "crapto1/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) { + for (uint16_t i = 0; i < 5; i++) { + part_sum ^= filter(st); + st = (st << 1) | ((j >> (3-i)) & 0x01) ; + } + 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 + +#define malloc_bitarray(x) __builtin_assume_aligned(_aligned_malloc(x, __BIGGEST_ALIGNMENT__), __BIGGEST_ALIGNMENT__) +#define free_bitarray(x) _aligned_free(x) + +static inline void clear_bitarray24(uint32_t *bitarray) +{ + memset(bitarray, 0x00, sizeof(uint32_t) * (1<<19)); +} + + +static inline uint32_t test_bit24(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(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(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]; + sprintf(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 %d 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 %d possible %s states for bitflip property %03x (%d (%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 %d possible %s states for bitflip property %03x (%d (%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 %d possible %s states for bitflip property %03x (%d (%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 %d possible %s states for bitflip property %03x (%d (%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; + + 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; +} \ No newline at end of file diff --git a/client/hardnested/tables/bitflip_0_001_states.bin.z b/client/hardnested/tables/bitflip_0_001_states.bin.z new file mode 100644 index 000000000..d697d83ce Binary files /dev/null and b/client/hardnested/tables/bitflip_0_001_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_003_states.bin.z b/client/hardnested/tables/bitflip_0_003_states.bin.z new file mode 100644 index 000000000..2973d69cb Binary files /dev/null and b/client/hardnested/tables/bitflip_0_003_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_005_states.bin.z b/client/hardnested/tables/bitflip_0_005_states.bin.z new file mode 100644 index 000000000..01b274abe Binary files /dev/null and b/client/hardnested/tables/bitflip_0_005_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_007_states.bin.z b/client/hardnested/tables/bitflip_0_007_states.bin.z new file mode 100644 index 000000000..8a2ee5530 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_007_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_009_states.bin.z b/client/hardnested/tables/bitflip_0_009_states.bin.z new file mode 100644 index 000000000..f1de49a74 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_009_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_00b_states.bin.z b/client/hardnested/tables/bitflip_0_00b_states.bin.z new file mode 100644 index 000000000..8c919a282 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_00b_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_00d_states.bin.z b/client/hardnested/tables/bitflip_0_00d_states.bin.z new file mode 100644 index 000000000..214457920 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_00d_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_00f_states.bin.z b/client/hardnested/tables/bitflip_0_00f_states.bin.z new file mode 100644 index 000000000..07f00ab05 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_00f_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_010_states.bin.z b/client/hardnested/tables/bitflip_0_010_states.bin.z new file mode 100644 index 000000000..3b5f8c3d1 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_010_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_014_states.bin.z b/client/hardnested/tables/bitflip_0_014_states.bin.z new file mode 100644 index 000000000..ec220c704 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_014_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_01c_states.bin.z b/client/hardnested/tables/bitflip_0_01c_states.bin.z new file mode 100644 index 000000000..3d38583d3 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_01c_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_021_states.bin.z b/client/hardnested/tables/bitflip_0_021_states.bin.z new file mode 100644 index 000000000..39fc37c15 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_021_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_023_states.bin.z b/client/hardnested/tables/bitflip_0_023_states.bin.z new file mode 100644 index 000000000..db4897a35 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_023_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_025_states.bin.z b/client/hardnested/tables/bitflip_0_025_states.bin.z new file mode 100644 index 000000000..339b9222f Binary files /dev/null and b/client/hardnested/tables/bitflip_0_025_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_027_states.bin.z b/client/hardnested/tables/bitflip_0_027_states.bin.z new file mode 100644 index 000000000..365da6804 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_027_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_029_states.bin.z b/client/hardnested/tables/bitflip_0_029_states.bin.z new file mode 100644 index 000000000..32da12571 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_029_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_02b_states.bin.z b/client/hardnested/tables/bitflip_0_02b_states.bin.z new file mode 100644 index 000000000..3cb26a7ee Binary files /dev/null and b/client/hardnested/tables/bitflip_0_02b_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_02d_states.bin.z b/client/hardnested/tables/bitflip_0_02d_states.bin.z new file mode 100644 index 000000000..84db51d15 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_02d_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_02f_states.bin.z b/client/hardnested/tables/bitflip_0_02f_states.bin.z new file mode 100644 index 000000000..8858e63b4 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_02f_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_030_states.bin.z b/client/hardnested/tables/bitflip_0_030_states.bin.z new file mode 100644 index 000000000..a9643322a Binary files /dev/null and b/client/hardnested/tables/bitflip_0_030_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_034_states.bin.z b/client/hardnested/tables/bitflip_0_034_states.bin.z new file mode 100644 index 000000000..959af96a9 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_034_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_03c_states.bin.z b/client/hardnested/tables/bitflip_0_03c_states.bin.z new file mode 100644 index 000000000..7ee384996 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_03c_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_040_states.bin.z b/client/hardnested/tables/bitflip_0_040_states.bin.z new file mode 100644 index 000000000..372d2d4ad Binary files /dev/null and b/client/hardnested/tables/bitflip_0_040_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_044_states.bin.z b/client/hardnested/tables/bitflip_0_044_states.bin.z new file mode 100644 index 000000000..ea9324375 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_044_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_04c_states.bin.z b/client/hardnested/tables/bitflip_0_04c_states.bin.z new file mode 100644 index 000000000..2bf23856d Binary files /dev/null and b/client/hardnested/tables/bitflip_0_04c_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_051_states.bin.z b/client/hardnested/tables/bitflip_0_051_states.bin.z new file mode 100644 index 000000000..0b78915aa Binary files /dev/null and b/client/hardnested/tables/bitflip_0_051_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_053_states.bin.z b/client/hardnested/tables/bitflip_0_053_states.bin.z new file mode 100644 index 000000000..700af31b9 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_053_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_055_states.bin.z b/client/hardnested/tables/bitflip_0_055_states.bin.z new file mode 100644 index 000000000..307828e64 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_055_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_057_states.bin.z b/client/hardnested/tables/bitflip_0_057_states.bin.z new file mode 100644 index 000000000..3e8d1b279 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_057_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_059_states.bin.z b/client/hardnested/tables/bitflip_0_059_states.bin.z new file mode 100644 index 000000000..1356800e0 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_059_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_05b_states.bin.z b/client/hardnested/tables/bitflip_0_05b_states.bin.z new file mode 100644 index 000000000..efe41d503 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_05b_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_05d_states.bin.z b/client/hardnested/tables/bitflip_0_05d_states.bin.z new file mode 100644 index 000000000..2830ce686 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_05d_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_05f_states.bin.z b/client/hardnested/tables/bitflip_0_05f_states.bin.z new file mode 100644 index 000000000..890893050 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_05f_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_064_states.bin.z b/client/hardnested/tables/bitflip_0_064_states.bin.z new file mode 100644 index 000000000..05cd17e54 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_064_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_06c_states.bin.z b/client/hardnested/tables/bitflip_0_06c_states.bin.z new file mode 100644 index 000000000..d787bcc99 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_06c_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_071_states.bin.z b/client/hardnested/tables/bitflip_0_071_states.bin.z new file mode 100644 index 000000000..2d2f4a1c2 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_071_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_073_states.bin.z b/client/hardnested/tables/bitflip_0_073_states.bin.z new file mode 100644 index 000000000..552cff66c Binary files /dev/null and b/client/hardnested/tables/bitflip_0_073_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_075_states.bin.z b/client/hardnested/tables/bitflip_0_075_states.bin.z new file mode 100644 index 000000000..e37d90e2a Binary files /dev/null and b/client/hardnested/tables/bitflip_0_075_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_077_states.bin.z b/client/hardnested/tables/bitflip_0_077_states.bin.z new file mode 100644 index 000000000..f03f0bba6 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_077_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_079_states.bin.z b/client/hardnested/tables/bitflip_0_079_states.bin.z new file mode 100644 index 000000000..b05646ac5 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_079_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_07b_states.bin.z b/client/hardnested/tables/bitflip_0_07b_states.bin.z new file mode 100644 index 000000000..184354a44 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_07b_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_07f_states.bin.z b/client/hardnested/tables/bitflip_0_07f_states.bin.z new file mode 100644 index 000000000..87ac36ab2 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_07f_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_081_states.bin.z b/client/hardnested/tables/bitflip_0_081_states.bin.z new file mode 100644 index 000000000..b8f66386b Binary files /dev/null and b/client/hardnested/tables/bitflip_0_081_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_083_states.bin.z b/client/hardnested/tables/bitflip_0_083_states.bin.z new file mode 100644 index 000000000..81c4c59f9 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_083_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_085_states.bin.z b/client/hardnested/tables/bitflip_0_085_states.bin.z new file mode 100644 index 000000000..e642accdf Binary files /dev/null and b/client/hardnested/tables/bitflip_0_085_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_087_states.bin.z b/client/hardnested/tables/bitflip_0_087_states.bin.z new file mode 100644 index 000000000..1a844e453 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_087_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_089_states.bin.z b/client/hardnested/tables/bitflip_0_089_states.bin.z new file mode 100644 index 000000000..d02b3c777 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_089_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_08b_states.bin.z b/client/hardnested/tables/bitflip_0_08b_states.bin.z new file mode 100644 index 000000000..9c546f94f Binary files /dev/null and b/client/hardnested/tables/bitflip_0_08b_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_08d_states.bin.z b/client/hardnested/tables/bitflip_0_08d_states.bin.z new file mode 100644 index 000000000..e0e985fcf Binary files /dev/null and b/client/hardnested/tables/bitflip_0_08d_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_08f_states.bin.z b/client/hardnested/tables/bitflip_0_08f_states.bin.z new file mode 100644 index 000000000..f5b38b584 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_08f_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_090_states.bin.z b/client/hardnested/tables/bitflip_0_090_states.bin.z new file mode 100644 index 000000000..f901235a3 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_090_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_094_states.bin.z b/client/hardnested/tables/bitflip_0_094_states.bin.z new file mode 100644 index 000000000..f97d41f4e Binary files /dev/null and b/client/hardnested/tables/bitflip_0_094_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_09c_states.bin.z b/client/hardnested/tables/bitflip_0_09c_states.bin.z new file mode 100644 index 000000000..7946dcf31 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_09c_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_0a1_states.bin.z b/client/hardnested/tables/bitflip_0_0a1_states.bin.z new file mode 100644 index 000000000..23198e8ae Binary files /dev/null and b/client/hardnested/tables/bitflip_0_0a1_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_0a3_states.bin.z b/client/hardnested/tables/bitflip_0_0a3_states.bin.z new file mode 100644 index 000000000..3d2cbe6d7 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_0a3_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_0a5_states.bin.z b/client/hardnested/tables/bitflip_0_0a5_states.bin.z new file mode 100644 index 000000000..9e6803572 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_0a5_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_0a7_states.bin.z b/client/hardnested/tables/bitflip_0_0a7_states.bin.z new file mode 100644 index 000000000..e7ad43a84 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_0a7_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_0a9_states.bin.z b/client/hardnested/tables/bitflip_0_0a9_states.bin.z new file mode 100644 index 000000000..cd17efb23 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_0a9_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_0ab_states.bin.z b/client/hardnested/tables/bitflip_0_0ab_states.bin.z new file mode 100644 index 000000000..8469638d5 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_0ab_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_0ad_states.bin.z b/client/hardnested/tables/bitflip_0_0ad_states.bin.z new file mode 100644 index 000000000..591851878 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_0ad_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_0af_states.bin.z b/client/hardnested/tables/bitflip_0_0af_states.bin.z new file mode 100644 index 000000000..51e59ea2e Binary files /dev/null and b/client/hardnested/tables/bitflip_0_0af_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_0b0_states.bin.z b/client/hardnested/tables/bitflip_0_0b0_states.bin.z new file mode 100644 index 000000000..09370ddf3 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_0b0_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_0b4_states.bin.z b/client/hardnested/tables/bitflip_0_0b4_states.bin.z new file mode 100644 index 000000000..4048a702c Binary files /dev/null and b/client/hardnested/tables/bitflip_0_0b4_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_0bc_states.bin.z b/client/hardnested/tables/bitflip_0_0bc_states.bin.z new file mode 100644 index 000000000..ab0b3755d Binary files /dev/null and b/client/hardnested/tables/bitflip_0_0bc_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_0c0_states.bin.z b/client/hardnested/tables/bitflip_0_0c0_states.bin.z new file mode 100644 index 000000000..d3f655b04 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_0c0_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_0c4_states.bin.z b/client/hardnested/tables/bitflip_0_0c4_states.bin.z new file mode 100644 index 000000000..d5c5f5edf Binary files /dev/null and b/client/hardnested/tables/bitflip_0_0c4_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_0cc_states.bin.z b/client/hardnested/tables/bitflip_0_0cc_states.bin.z new file mode 100644 index 000000000..868afc9f9 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_0cc_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_0d1_states.bin.z b/client/hardnested/tables/bitflip_0_0d1_states.bin.z new file mode 100644 index 000000000..f7dd752f4 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_0d1_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_0d3_states.bin.z b/client/hardnested/tables/bitflip_0_0d3_states.bin.z new file mode 100644 index 000000000..68ef2a6d5 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_0d3_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_0d5_states.bin.z b/client/hardnested/tables/bitflip_0_0d5_states.bin.z new file mode 100644 index 000000000..7720f54a3 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_0d5_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_0d7_states.bin.z b/client/hardnested/tables/bitflip_0_0d7_states.bin.z new file mode 100644 index 000000000..5f05c9cd3 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_0d7_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_0d9_states.bin.z b/client/hardnested/tables/bitflip_0_0d9_states.bin.z new file mode 100644 index 000000000..f9ead3d9f Binary files /dev/null and b/client/hardnested/tables/bitflip_0_0d9_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_0db_states.bin.z b/client/hardnested/tables/bitflip_0_0db_states.bin.z new file mode 100644 index 000000000..c272e158b Binary files /dev/null and b/client/hardnested/tables/bitflip_0_0db_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_0dd_states.bin.z b/client/hardnested/tables/bitflip_0_0dd_states.bin.z new file mode 100644 index 000000000..6247d26df Binary files /dev/null and b/client/hardnested/tables/bitflip_0_0dd_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_0df_states.bin.z b/client/hardnested/tables/bitflip_0_0df_states.bin.z new file mode 100644 index 000000000..63e00d2cd Binary files /dev/null and b/client/hardnested/tables/bitflip_0_0df_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_0e4_states.bin.z b/client/hardnested/tables/bitflip_0_0e4_states.bin.z new file mode 100644 index 000000000..5b4d867fd Binary files /dev/null and b/client/hardnested/tables/bitflip_0_0e4_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_0ec_states.bin.z b/client/hardnested/tables/bitflip_0_0ec_states.bin.z new file mode 100644 index 000000000..764188911 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_0ec_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_0f1_states.bin.z b/client/hardnested/tables/bitflip_0_0f1_states.bin.z new file mode 100644 index 000000000..9740a1a39 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_0f1_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_0f3_states.bin.z b/client/hardnested/tables/bitflip_0_0f3_states.bin.z new file mode 100644 index 000000000..8f783f784 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_0f3_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_0f5_states.bin.z b/client/hardnested/tables/bitflip_0_0f5_states.bin.z new file mode 100644 index 000000000..aa13d9a1d Binary files /dev/null and b/client/hardnested/tables/bitflip_0_0f5_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_0f7_states.bin.z b/client/hardnested/tables/bitflip_0_0f7_states.bin.z new file mode 100644 index 000000000..6d19ae6ae Binary files /dev/null and b/client/hardnested/tables/bitflip_0_0f7_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_0f9_states.bin.z b/client/hardnested/tables/bitflip_0_0f9_states.bin.z new file mode 100644 index 000000000..2606b9409 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_0f9_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_0fb_states.bin.z b/client/hardnested/tables/bitflip_0_0fb_states.bin.z new file mode 100644 index 000000000..b263f23ae Binary files /dev/null and b/client/hardnested/tables/bitflip_0_0fb_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_0fd_states.bin.z b/client/hardnested/tables/bitflip_0_0fd_states.bin.z new file mode 100644 index 000000000..68b581ee2 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_0fd_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_0ff_states.bin.z b/client/hardnested/tables/bitflip_0_0ff_states.bin.z new file mode 100644 index 000000000..f73f50d8e Binary files /dev/null and b/client/hardnested/tables/bitflip_0_0ff_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_104_states.bin.z b/client/hardnested/tables/bitflip_0_104_states.bin.z new file mode 100644 index 000000000..a65adef0e Binary files /dev/null and b/client/hardnested/tables/bitflip_0_104_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_10c_states.bin.z b/client/hardnested/tables/bitflip_0_10c_states.bin.z new file mode 100644 index 000000000..f9cb945ef Binary files /dev/null and b/client/hardnested/tables/bitflip_0_10c_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_111_states.bin.z b/client/hardnested/tables/bitflip_0_111_states.bin.z new file mode 100644 index 000000000..10cbb8de5 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_111_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_113_states.bin.z b/client/hardnested/tables/bitflip_0_113_states.bin.z new file mode 100644 index 000000000..b350136d5 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_113_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_115_states.bin.z b/client/hardnested/tables/bitflip_0_115_states.bin.z new file mode 100644 index 000000000..c6661ae8c Binary files /dev/null and b/client/hardnested/tables/bitflip_0_115_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_117_states.bin.z b/client/hardnested/tables/bitflip_0_117_states.bin.z new file mode 100644 index 000000000..647feb09f Binary files /dev/null and b/client/hardnested/tables/bitflip_0_117_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_119_states.bin.z b/client/hardnested/tables/bitflip_0_119_states.bin.z new file mode 100644 index 000000000..289598b1a Binary files /dev/null and b/client/hardnested/tables/bitflip_0_119_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_11b_states.bin.z b/client/hardnested/tables/bitflip_0_11b_states.bin.z new file mode 100644 index 000000000..099dab124 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_11b_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_11d_states.bin.z b/client/hardnested/tables/bitflip_0_11d_states.bin.z new file mode 100644 index 000000000..3d9511d85 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_11d_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_11f_states.bin.z b/client/hardnested/tables/bitflip_0_11f_states.bin.z new file mode 100644 index 000000000..bb92ebe2a Binary files /dev/null and b/client/hardnested/tables/bitflip_0_11f_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_124_states.bin.z b/client/hardnested/tables/bitflip_0_124_states.bin.z new file mode 100644 index 000000000..0a37cc5ce Binary files /dev/null and b/client/hardnested/tables/bitflip_0_124_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_12c_states.bin.z b/client/hardnested/tables/bitflip_0_12c_states.bin.z new file mode 100644 index 000000000..ce9a966fa Binary files /dev/null and b/client/hardnested/tables/bitflip_0_12c_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_131_states.bin.z b/client/hardnested/tables/bitflip_0_131_states.bin.z new file mode 100644 index 000000000..6928656f3 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_131_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_133_states.bin.z b/client/hardnested/tables/bitflip_0_133_states.bin.z new file mode 100644 index 000000000..acdb9d972 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_133_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_135_states.bin.z b/client/hardnested/tables/bitflip_0_135_states.bin.z new file mode 100644 index 000000000..8ae5ed323 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_135_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_137_states.bin.z b/client/hardnested/tables/bitflip_0_137_states.bin.z new file mode 100644 index 000000000..73202f119 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_137_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_139_states.bin.z b/client/hardnested/tables/bitflip_0_139_states.bin.z new file mode 100644 index 000000000..e43946366 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_139_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_13b_states.bin.z b/client/hardnested/tables/bitflip_0_13b_states.bin.z new file mode 100644 index 000000000..742c3309b Binary files /dev/null and b/client/hardnested/tables/bitflip_0_13b_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_13d_states.bin.z b/client/hardnested/tables/bitflip_0_13d_states.bin.z new file mode 100644 index 000000000..4b95e1ca9 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_13d_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_13f_states.bin.z b/client/hardnested/tables/bitflip_0_13f_states.bin.z new file mode 100644 index 000000000..469361ed5 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_13f_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_141_states.bin.z b/client/hardnested/tables/bitflip_0_141_states.bin.z new file mode 100644 index 000000000..61746bf77 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_141_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_143_states.bin.z b/client/hardnested/tables/bitflip_0_143_states.bin.z new file mode 100644 index 000000000..685cf9d00 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_143_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_145_states.bin.z b/client/hardnested/tables/bitflip_0_145_states.bin.z new file mode 100644 index 000000000..eab4935d1 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_145_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_147_states.bin.z b/client/hardnested/tables/bitflip_0_147_states.bin.z new file mode 100644 index 000000000..4d6674400 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_147_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_149_states.bin.z b/client/hardnested/tables/bitflip_0_149_states.bin.z new file mode 100644 index 000000000..b9da604a0 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_149_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_14b_states.bin.z b/client/hardnested/tables/bitflip_0_14b_states.bin.z new file mode 100644 index 000000000..608337840 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_14b_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_14d_states.bin.z b/client/hardnested/tables/bitflip_0_14d_states.bin.z new file mode 100644 index 000000000..fd8e92850 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_14d_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_14f_states.bin.z b/client/hardnested/tables/bitflip_0_14f_states.bin.z new file mode 100644 index 000000000..f8af0a6f0 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_14f_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_150_states.bin.z b/client/hardnested/tables/bitflip_0_150_states.bin.z new file mode 100644 index 000000000..587807efd Binary files /dev/null and b/client/hardnested/tables/bitflip_0_150_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_154_states.bin.z b/client/hardnested/tables/bitflip_0_154_states.bin.z new file mode 100644 index 000000000..56cb4f168 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_154_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_15c_states.bin.z b/client/hardnested/tables/bitflip_0_15c_states.bin.z new file mode 100644 index 000000000..4eb487853 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_15c_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_161_states.bin.z b/client/hardnested/tables/bitflip_0_161_states.bin.z new file mode 100644 index 000000000..ef9f67c09 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_161_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_163_states.bin.z b/client/hardnested/tables/bitflip_0_163_states.bin.z new file mode 100644 index 000000000..f08b3e0fe Binary files /dev/null and b/client/hardnested/tables/bitflip_0_163_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_165_states.bin.z b/client/hardnested/tables/bitflip_0_165_states.bin.z new file mode 100644 index 000000000..9e846f209 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_165_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_167_states.bin.z b/client/hardnested/tables/bitflip_0_167_states.bin.z new file mode 100644 index 000000000..8aae9133c Binary files /dev/null and b/client/hardnested/tables/bitflip_0_167_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_169_states.bin.z b/client/hardnested/tables/bitflip_0_169_states.bin.z new file mode 100644 index 000000000..a42857b5a Binary files /dev/null and b/client/hardnested/tables/bitflip_0_169_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_16b_states.bin.z b/client/hardnested/tables/bitflip_0_16b_states.bin.z new file mode 100644 index 000000000..426210add Binary files /dev/null and b/client/hardnested/tables/bitflip_0_16b_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_16d_states.bin.z b/client/hardnested/tables/bitflip_0_16d_states.bin.z new file mode 100644 index 000000000..5640076fd Binary files /dev/null and b/client/hardnested/tables/bitflip_0_16d_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_16f_states.bin.z b/client/hardnested/tables/bitflip_0_16f_states.bin.z new file mode 100644 index 000000000..39d0d0801 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_16f_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_170_states.bin.z b/client/hardnested/tables/bitflip_0_170_states.bin.z new file mode 100644 index 000000000..f49f4d249 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_170_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_174_states.bin.z b/client/hardnested/tables/bitflip_0_174_states.bin.z new file mode 100644 index 000000000..66acfea97 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_174_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_17c_states.bin.z b/client/hardnested/tables/bitflip_0_17c_states.bin.z new file mode 100644 index 000000000..c8f72c15f Binary files /dev/null and b/client/hardnested/tables/bitflip_0_17c_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_184_states.bin.z b/client/hardnested/tables/bitflip_0_184_states.bin.z new file mode 100644 index 000000000..caa5e8bd4 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_184_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_18c_states.bin.z b/client/hardnested/tables/bitflip_0_18c_states.bin.z new file mode 100644 index 000000000..da5c55a2d Binary files /dev/null and b/client/hardnested/tables/bitflip_0_18c_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_191_states.bin.z b/client/hardnested/tables/bitflip_0_191_states.bin.z new file mode 100644 index 000000000..5a4b9aef1 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_191_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_193_states.bin.z b/client/hardnested/tables/bitflip_0_193_states.bin.z new file mode 100644 index 000000000..5f7e0b484 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_193_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_195_states.bin.z b/client/hardnested/tables/bitflip_0_195_states.bin.z new file mode 100644 index 000000000..e15df41f5 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_195_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_197_states.bin.z b/client/hardnested/tables/bitflip_0_197_states.bin.z new file mode 100644 index 000000000..d4b5fd31c Binary files /dev/null and b/client/hardnested/tables/bitflip_0_197_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_199_states.bin.z b/client/hardnested/tables/bitflip_0_199_states.bin.z new file mode 100644 index 000000000..9117c86da Binary files /dev/null and b/client/hardnested/tables/bitflip_0_199_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_19b_states.bin.z b/client/hardnested/tables/bitflip_0_19b_states.bin.z new file mode 100644 index 000000000..ae144de8c Binary files /dev/null and b/client/hardnested/tables/bitflip_0_19b_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_19d_states.bin.z b/client/hardnested/tables/bitflip_0_19d_states.bin.z new file mode 100644 index 000000000..1b7f08b3d Binary files /dev/null and b/client/hardnested/tables/bitflip_0_19d_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_19f_states.bin.z b/client/hardnested/tables/bitflip_0_19f_states.bin.z new file mode 100644 index 000000000..81ef023c3 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_19f_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_1a4_states.bin.z b/client/hardnested/tables/bitflip_0_1a4_states.bin.z new file mode 100644 index 000000000..af0f72086 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_1a4_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_1ac_states.bin.z b/client/hardnested/tables/bitflip_0_1ac_states.bin.z new file mode 100644 index 000000000..5b2ddbf57 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_1ac_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_1b1_states.bin.z b/client/hardnested/tables/bitflip_0_1b1_states.bin.z new file mode 100644 index 000000000..61ce91072 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_1b1_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_1b3_states.bin.z b/client/hardnested/tables/bitflip_0_1b3_states.bin.z new file mode 100644 index 000000000..3825cf8b8 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_1b3_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_1b5_states.bin.z b/client/hardnested/tables/bitflip_0_1b5_states.bin.z new file mode 100644 index 000000000..7750ad78f Binary files /dev/null and b/client/hardnested/tables/bitflip_0_1b5_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_1b7_states.bin.z b/client/hardnested/tables/bitflip_0_1b7_states.bin.z new file mode 100644 index 000000000..1663d7a5e Binary files /dev/null and b/client/hardnested/tables/bitflip_0_1b7_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_1b9_states.bin.z b/client/hardnested/tables/bitflip_0_1b9_states.bin.z new file mode 100644 index 000000000..f6b102d9a Binary files /dev/null and b/client/hardnested/tables/bitflip_0_1b9_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_1bb_states.bin.z b/client/hardnested/tables/bitflip_0_1bb_states.bin.z new file mode 100644 index 000000000..0e6675818 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_1bb_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_1bd_states.bin.z b/client/hardnested/tables/bitflip_0_1bd_states.bin.z new file mode 100644 index 000000000..8e991fcba Binary files /dev/null and b/client/hardnested/tables/bitflip_0_1bd_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_1bf_states.bin.z b/client/hardnested/tables/bitflip_0_1bf_states.bin.z new file mode 100644 index 000000000..9fe373bd8 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_1bf_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_1c1_states.bin.z b/client/hardnested/tables/bitflip_0_1c1_states.bin.z new file mode 100644 index 000000000..1d6e2df38 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_1c1_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_1c3_states.bin.z b/client/hardnested/tables/bitflip_0_1c3_states.bin.z new file mode 100644 index 000000000..c47845644 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_1c3_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_1c5_states.bin.z b/client/hardnested/tables/bitflip_0_1c5_states.bin.z new file mode 100644 index 000000000..fd67e955c Binary files /dev/null and b/client/hardnested/tables/bitflip_0_1c5_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_1c9_states.bin.z b/client/hardnested/tables/bitflip_0_1c9_states.bin.z new file mode 100644 index 000000000..88ab2a968 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_1c9_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_1cb_states.bin.z b/client/hardnested/tables/bitflip_0_1cb_states.bin.z new file mode 100644 index 000000000..31bd47cc6 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_1cb_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_1d0_states.bin.z b/client/hardnested/tables/bitflip_0_1d0_states.bin.z new file mode 100644 index 000000000..8ac5e4099 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_1d0_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_1d4_states.bin.z b/client/hardnested/tables/bitflip_0_1d4_states.bin.z new file mode 100644 index 000000000..ad91ddea9 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_1d4_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_1dc_states.bin.z b/client/hardnested/tables/bitflip_0_1dc_states.bin.z new file mode 100644 index 000000000..f5b1dbb10 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_1dc_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_1e1_states.bin.z b/client/hardnested/tables/bitflip_0_1e1_states.bin.z new file mode 100644 index 000000000..d475d9778 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_1e1_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_1e3_states.bin.z b/client/hardnested/tables/bitflip_0_1e3_states.bin.z new file mode 100644 index 000000000..64884ba56 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_1e3_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_1e5_states.bin.z b/client/hardnested/tables/bitflip_0_1e5_states.bin.z new file mode 100644 index 000000000..cd80ef830 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_1e5_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_1e7_states.bin.z b/client/hardnested/tables/bitflip_0_1e7_states.bin.z new file mode 100644 index 000000000..42483bdd5 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_1e7_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_1e9_states.bin.z b/client/hardnested/tables/bitflip_0_1e9_states.bin.z new file mode 100644 index 000000000..d133b27a2 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_1e9_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_1eb_states.bin.z b/client/hardnested/tables/bitflip_0_1eb_states.bin.z new file mode 100644 index 000000000..7a3b347bb Binary files /dev/null and b/client/hardnested/tables/bitflip_0_1eb_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_1ed_states.bin.z b/client/hardnested/tables/bitflip_0_1ed_states.bin.z new file mode 100644 index 000000000..db5d216aa Binary files /dev/null and b/client/hardnested/tables/bitflip_0_1ed_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_1ef_states.bin.z b/client/hardnested/tables/bitflip_0_1ef_states.bin.z new file mode 100644 index 000000000..15eeba048 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_1ef_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_1f0_states.bin.z b/client/hardnested/tables/bitflip_0_1f0_states.bin.z new file mode 100644 index 000000000..fb3df75b7 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_1f0_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_1f4_states.bin.z b/client/hardnested/tables/bitflip_0_1f4_states.bin.z new file mode 100644 index 000000000..fe2d56c90 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_1f4_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_1fc_states.bin.z b/client/hardnested/tables/bitflip_0_1fc_states.bin.z new file mode 100644 index 000000000..791352bfd Binary files /dev/null and b/client/hardnested/tables/bitflip_0_1fc_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_210_states.bin.z b/client/hardnested/tables/bitflip_0_210_states.bin.z new file mode 100644 index 000000000..479bacb03 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_210_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_225_states.bin.z b/client/hardnested/tables/bitflip_0_225_states.bin.z new file mode 100644 index 000000000..a4cc5d58c Binary files /dev/null and b/client/hardnested/tables/bitflip_0_225_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_227_states.bin.z b/client/hardnested/tables/bitflip_0_227_states.bin.z new file mode 100644 index 000000000..f7bb63eb7 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_227_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_22d_states.bin.z b/client/hardnested/tables/bitflip_0_22d_states.bin.z new file mode 100644 index 000000000..4e5b2ff27 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_22d_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_22f_states.bin.z b/client/hardnested/tables/bitflip_0_22f_states.bin.z new file mode 100644 index 000000000..f8686dba6 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_22f_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_240_states.bin.z b/client/hardnested/tables/bitflip_0_240_states.bin.z new file mode 100644 index 000000000..e4f4b6ac6 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_240_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_275_states.bin.z b/client/hardnested/tables/bitflip_0_275_states.bin.z new file mode 100644 index 000000000..a4cc5d58c Binary files /dev/null and b/client/hardnested/tables/bitflip_0_275_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_277_states.bin.z b/client/hardnested/tables/bitflip_0_277_states.bin.z new file mode 100644 index 000000000..f7bb63eb7 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_277_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_27f_states.bin.z b/client/hardnested/tables/bitflip_0_27f_states.bin.z new file mode 100644 index 000000000..f8686dba6 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_27f_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_294_states.bin.z b/client/hardnested/tables/bitflip_0_294_states.bin.z new file mode 100644 index 000000000..c8a8cf4a0 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_294_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_2a1_states.bin.z b/client/hardnested/tables/bitflip_0_2a1_states.bin.z new file mode 100644 index 000000000..a4cc5d58c Binary files /dev/null and b/client/hardnested/tables/bitflip_0_2a1_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_2a3_states.bin.z b/client/hardnested/tables/bitflip_0_2a3_states.bin.z new file mode 100644 index 000000000..f7bb63eb7 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_2a3_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_2a9_states.bin.z b/client/hardnested/tables/bitflip_0_2a9_states.bin.z new file mode 100644 index 000000000..4e5b2ff27 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_2a9_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_2ab_states.bin.z b/client/hardnested/tables/bitflip_0_2ab_states.bin.z new file mode 100644 index 000000000..f8686dba6 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_2ab_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_2c4_states.bin.z b/client/hardnested/tables/bitflip_0_2c4_states.bin.z new file mode 100644 index 000000000..c8a8cf4a0 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_2c4_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_2f1_states.bin.z b/client/hardnested/tables/bitflip_0_2f1_states.bin.z new file mode 100644 index 000000000..a4cc5d58c Binary files /dev/null and b/client/hardnested/tables/bitflip_0_2f1_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_2f3_states.bin.z b/client/hardnested/tables/bitflip_0_2f3_states.bin.z new file mode 100644 index 000000000..f7bb63eb7 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_2f3_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_2f9_states.bin.z b/client/hardnested/tables/bitflip_0_2f9_states.bin.z new file mode 100644 index 000000000..4e5b2ff27 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_2f9_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_2fb_states.bin.z b/client/hardnested/tables/bitflip_0_2fb_states.bin.z new file mode 100644 index 000000000..f8686dba6 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_2fb_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_335_states.bin.z b/client/hardnested/tables/bitflip_0_335_states.bin.z new file mode 100644 index 000000000..a4cc5d58c Binary files /dev/null and b/client/hardnested/tables/bitflip_0_335_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_337_states.bin.z b/client/hardnested/tables/bitflip_0_337_states.bin.z new file mode 100644 index 000000000..f7bb63eb7 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_337_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_33d_states.bin.z b/client/hardnested/tables/bitflip_0_33d_states.bin.z new file mode 100644 index 000000000..4e5b2ff27 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_33d_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_33f_states.bin.z b/client/hardnested/tables/bitflip_0_33f_states.bin.z new file mode 100644 index 000000000..f8686dba6 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_33f_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_350_states.bin.z b/client/hardnested/tables/bitflip_0_350_states.bin.z new file mode 100644 index 000000000..479bacb03 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_350_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_365_states.bin.z b/client/hardnested/tables/bitflip_0_365_states.bin.z new file mode 100644 index 000000000..a4cc5d58c Binary files /dev/null and b/client/hardnested/tables/bitflip_0_365_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_367_states.bin.z b/client/hardnested/tables/bitflip_0_367_states.bin.z new file mode 100644 index 000000000..f7bb63eb7 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_367_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_36d_states.bin.z b/client/hardnested/tables/bitflip_0_36d_states.bin.z new file mode 100644 index 000000000..4e5b2ff27 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_36d_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_36f_states.bin.z b/client/hardnested/tables/bitflip_0_36f_states.bin.z new file mode 100644 index 000000000..f8686dba6 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_36f_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_384_states.bin.z b/client/hardnested/tables/bitflip_0_384_states.bin.z new file mode 100644 index 000000000..c8a8cf4a0 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_384_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_3b1_states.bin.z b/client/hardnested/tables/bitflip_0_3b1_states.bin.z new file mode 100644 index 000000000..a4cc5d58c Binary files /dev/null and b/client/hardnested/tables/bitflip_0_3b1_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_3b3_states.bin.z b/client/hardnested/tables/bitflip_0_3b3_states.bin.z new file mode 100644 index 000000000..f7bb63eb7 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_3b3_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_3b9_states.bin.z b/client/hardnested/tables/bitflip_0_3b9_states.bin.z new file mode 100644 index 000000000..4e5b2ff27 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_3b9_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_3bb_states.bin.z b/client/hardnested/tables/bitflip_0_3bb_states.bin.z new file mode 100644 index 000000000..f8686dba6 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_3bb_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_3d4_states.bin.z b/client/hardnested/tables/bitflip_0_3d4_states.bin.z new file mode 100644 index 000000000..c8a8cf4a0 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_3d4_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_3e1_states.bin.z b/client/hardnested/tables/bitflip_0_3e1_states.bin.z new file mode 100644 index 000000000..a4cc5d58c Binary files /dev/null and b/client/hardnested/tables/bitflip_0_3e1_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_3e3_states.bin.z b/client/hardnested/tables/bitflip_0_3e3_states.bin.z new file mode 100644 index 000000000..f7bb63eb7 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_3e3_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_3e9_states.bin.z b/client/hardnested/tables/bitflip_0_3e9_states.bin.z new file mode 100644 index 000000000..4e5b2ff27 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_3e9_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_0_3eb_states.bin.z b/client/hardnested/tables/bitflip_0_3eb_states.bin.z new file mode 100644 index 000000000..f8686dba6 Binary files /dev/null and b/client/hardnested/tables/bitflip_0_3eb_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_002_states.bin.z b/client/hardnested/tables/bitflip_1_002_states.bin.z new file mode 100644 index 000000000..226c37a2f Binary files /dev/null and b/client/hardnested/tables/bitflip_1_002_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_008_states.bin.z b/client/hardnested/tables/bitflip_1_008_states.bin.z new file mode 100644 index 000000000..209bf5e9e Binary files /dev/null and b/client/hardnested/tables/bitflip_1_008_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_00a_states.bin.z b/client/hardnested/tables/bitflip_1_00a_states.bin.z new file mode 100644 index 000000000..63f0a7a5e Binary files /dev/null and b/client/hardnested/tables/bitflip_1_00a_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_012_states.bin.z b/client/hardnested/tables/bitflip_1_012_states.bin.z new file mode 100644 index 000000000..659e697f2 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_012_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_018_states.bin.z b/client/hardnested/tables/bitflip_1_018_states.bin.z new file mode 100644 index 000000000..b825cfd6c Binary files /dev/null and b/client/hardnested/tables/bitflip_1_018_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_01a_states.bin.z b/client/hardnested/tables/bitflip_1_01a_states.bin.z new file mode 100644 index 000000000..61d252b20 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_01a_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_020_states.bin.z b/client/hardnested/tables/bitflip_1_020_states.bin.z new file mode 100644 index 000000000..cc78af68f Binary files /dev/null and b/client/hardnested/tables/bitflip_1_020_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_028_states.bin.z b/client/hardnested/tables/bitflip_1_028_states.bin.z new file mode 100644 index 000000000..1137886b1 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_028_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_02a_states.bin.z b/client/hardnested/tables/bitflip_1_02a_states.bin.z new file mode 100644 index 000000000..12829c1bf Binary files /dev/null and b/client/hardnested/tables/bitflip_1_02a_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_02e_states.bin.z b/client/hardnested/tables/bitflip_1_02e_states.bin.z new file mode 100644 index 000000000..44fb65c0d Binary files /dev/null and b/client/hardnested/tables/bitflip_1_02e_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_032_states.bin.z b/client/hardnested/tables/bitflip_1_032_states.bin.z new file mode 100644 index 000000000..a8350cc17 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_032_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_036_states.bin.z b/client/hardnested/tables/bitflip_1_036_states.bin.z new file mode 100644 index 000000000..c14426d0b Binary files /dev/null and b/client/hardnested/tables/bitflip_1_036_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_038_states.bin.z b/client/hardnested/tables/bitflip_1_038_states.bin.z new file mode 100644 index 000000000..ec0b39af2 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_038_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_03a_states.bin.z b/client/hardnested/tables/bitflip_1_03a_states.bin.z new file mode 100644 index 000000000..e301254b9 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_03a_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_03e_states.bin.z b/client/hardnested/tables/bitflip_1_03e_states.bin.z new file mode 100644 index 000000000..9e5c059f5 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_03e_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_040_states.bin.z b/client/hardnested/tables/bitflip_1_040_states.bin.z new file mode 100644 index 000000000..d3f655b04 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_040_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_042_states.bin.z b/client/hardnested/tables/bitflip_1_042_states.bin.z new file mode 100644 index 000000000..d324368a6 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_042_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_046_states.bin.z b/client/hardnested/tables/bitflip_1_046_states.bin.z new file mode 100644 index 000000000..ff59e7409 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_046_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_048_states.bin.z b/client/hardnested/tables/bitflip_1_048_states.bin.z new file mode 100644 index 000000000..e21985aa3 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_048_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_04a_states.bin.z b/client/hardnested/tables/bitflip_1_04a_states.bin.z new file mode 100644 index 000000000..45c58fce2 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_04a_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_04e_states.bin.z b/client/hardnested/tables/bitflip_1_04e_states.bin.z new file mode 100644 index 000000000..3966d1b10 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_04e_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_052_states.bin.z b/client/hardnested/tables/bitflip_1_052_states.bin.z new file mode 100644 index 000000000..f0be53efc Binary files /dev/null and b/client/hardnested/tables/bitflip_1_052_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_056_states.bin.z b/client/hardnested/tables/bitflip_1_056_states.bin.z new file mode 100644 index 000000000..e92d411b7 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_056_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_058_states.bin.z b/client/hardnested/tables/bitflip_1_058_states.bin.z new file mode 100644 index 000000000..005459173 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_058_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_05a_states.bin.z b/client/hardnested/tables/bitflip_1_05a_states.bin.z new file mode 100644 index 000000000..1dfa63c70 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_05a_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_05e_states.bin.z b/client/hardnested/tables/bitflip_1_05e_states.bin.z new file mode 100644 index 000000000..dc0789685 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_05e_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_060_states.bin.z b/client/hardnested/tables/bitflip_1_060_states.bin.z new file mode 100644 index 000000000..72477c138 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_060_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_062_states.bin.z b/client/hardnested/tables/bitflip_1_062_states.bin.z new file mode 100644 index 000000000..53e85964a Binary files /dev/null and b/client/hardnested/tables/bitflip_1_062_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_066_states.bin.z b/client/hardnested/tables/bitflip_1_066_states.bin.z new file mode 100644 index 000000000..de23de8b3 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_066_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_068_states.bin.z b/client/hardnested/tables/bitflip_1_068_states.bin.z new file mode 100644 index 000000000..08b3e5439 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_068_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_06a_states.bin.z b/client/hardnested/tables/bitflip_1_06a_states.bin.z new file mode 100644 index 000000000..052898c7f Binary files /dev/null and b/client/hardnested/tables/bitflip_1_06a_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_06e_states.bin.z b/client/hardnested/tables/bitflip_1_06e_states.bin.z new file mode 100644 index 000000000..5e678bd47 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_06e_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_072_states.bin.z b/client/hardnested/tables/bitflip_1_072_states.bin.z new file mode 100644 index 000000000..404b482d8 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_072_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_076_states.bin.z b/client/hardnested/tables/bitflip_1_076_states.bin.z new file mode 100644 index 000000000..ac58f16e5 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_076_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_078_states.bin.z b/client/hardnested/tables/bitflip_1_078_states.bin.z new file mode 100644 index 000000000..47474d218 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_078_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_07a_states.bin.z b/client/hardnested/tables/bitflip_1_07a_states.bin.z new file mode 100644 index 000000000..8b4d446d6 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_07a_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_07e_states.bin.z b/client/hardnested/tables/bitflip_1_07e_states.bin.z new file mode 100644 index 000000000..dff5034c5 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_07e_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_080_states.bin.z b/client/hardnested/tables/bitflip_1_080_states.bin.z new file mode 100644 index 000000000..372d2d4ad Binary files /dev/null and b/client/hardnested/tables/bitflip_1_080_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_082_states.bin.z b/client/hardnested/tables/bitflip_1_082_states.bin.z new file mode 100644 index 000000000..5d688299c Binary files /dev/null and b/client/hardnested/tables/bitflip_1_082_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_086_states.bin.z b/client/hardnested/tables/bitflip_1_086_states.bin.z new file mode 100644 index 000000000..e640e39c6 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_086_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_088_states.bin.z b/client/hardnested/tables/bitflip_1_088_states.bin.z new file mode 100644 index 000000000..07dae4760 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_088_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_08a_states.bin.z b/client/hardnested/tables/bitflip_1_08a_states.bin.z new file mode 100644 index 000000000..449c46f3c Binary files /dev/null and b/client/hardnested/tables/bitflip_1_08a_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_08e_states.bin.z b/client/hardnested/tables/bitflip_1_08e_states.bin.z new file mode 100644 index 000000000..bdea7a0f1 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_08e_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_092_states.bin.z b/client/hardnested/tables/bitflip_1_092_states.bin.z new file mode 100644 index 000000000..6147f3fdd Binary files /dev/null and b/client/hardnested/tables/bitflip_1_092_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_096_states.bin.z b/client/hardnested/tables/bitflip_1_096_states.bin.z new file mode 100644 index 000000000..575a38314 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_096_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_098_states.bin.z b/client/hardnested/tables/bitflip_1_098_states.bin.z new file mode 100644 index 000000000..dee21c52a Binary files /dev/null and b/client/hardnested/tables/bitflip_1_098_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_09a_states.bin.z b/client/hardnested/tables/bitflip_1_09a_states.bin.z new file mode 100644 index 000000000..c4d76b453 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_09a_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_09e_states.bin.z b/client/hardnested/tables/bitflip_1_09e_states.bin.z new file mode 100644 index 000000000..dd57c590e Binary files /dev/null and b/client/hardnested/tables/bitflip_1_09e_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_0a0_states.bin.z b/client/hardnested/tables/bitflip_1_0a0_states.bin.z new file mode 100644 index 000000000..32880a5cd Binary files /dev/null and b/client/hardnested/tables/bitflip_1_0a0_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_0a2_states.bin.z b/client/hardnested/tables/bitflip_1_0a2_states.bin.z new file mode 100644 index 000000000..25d53d5f6 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_0a2_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_0a6_states.bin.z b/client/hardnested/tables/bitflip_1_0a6_states.bin.z new file mode 100644 index 000000000..ca1f5f93e Binary files /dev/null and b/client/hardnested/tables/bitflip_1_0a6_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_0a8_states.bin.z b/client/hardnested/tables/bitflip_1_0a8_states.bin.z new file mode 100644 index 000000000..c7d501ca4 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_0a8_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_0aa_states.bin.z b/client/hardnested/tables/bitflip_1_0aa_states.bin.z new file mode 100644 index 000000000..5c194d179 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_0aa_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_0ae_states.bin.z b/client/hardnested/tables/bitflip_1_0ae_states.bin.z new file mode 100644 index 000000000..2ce45b017 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_0ae_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_0b2_states.bin.z b/client/hardnested/tables/bitflip_1_0b2_states.bin.z new file mode 100644 index 000000000..d81106d05 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_0b2_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_0b6_states.bin.z b/client/hardnested/tables/bitflip_1_0b6_states.bin.z new file mode 100644 index 000000000..e8c99c170 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_0b6_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_0b8_states.bin.z b/client/hardnested/tables/bitflip_1_0b8_states.bin.z new file mode 100644 index 000000000..25e777872 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_0b8_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_0ba_states.bin.z b/client/hardnested/tables/bitflip_1_0ba_states.bin.z new file mode 100644 index 000000000..240130a6c Binary files /dev/null and b/client/hardnested/tables/bitflip_1_0ba_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_0be_states.bin.z b/client/hardnested/tables/bitflip_1_0be_states.bin.z new file mode 100644 index 000000000..05aca3b6c Binary files /dev/null and b/client/hardnested/tables/bitflip_1_0be_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_0c0_states.bin.z b/client/hardnested/tables/bitflip_1_0c0_states.bin.z new file mode 100644 index 000000000..d3f655b04 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_0c0_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_0c2_states.bin.z b/client/hardnested/tables/bitflip_1_0c2_states.bin.z new file mode 100644 index 000000000..cbbb63701 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_0c2_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_0c6_states.bin.z b/client/hardnested/tables/bitflip_1_0c6_states.bin.z new file mode 100644 index 000000000..95d162000 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_0c6_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_0c8_states.bin.z b/client/hardnested/tables/bitflip_1_0c8_states.bin.z new file mode 100644 index 000000000..5eca50e2e Binary files /dev/null and b/client/hardnested/tables/bitflip_1_0c8_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_0ca_states.bin.z b/client/hardnested/tables/bitflip_1_0ca_states.bin.z new file mode 100644 index 000000000..500be7d66 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_0ca_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_0ce_states.bin.z b/client/hardnested/tables/bitflip_1_0ce_states.bin.z new file mode 100644 index 000000000..583dc35e1 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_0ce_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_0d2_states.bin.z b/client/hardnested/tables/bitflip_1_0d2_states.bin.z new file mode 100644 index 000000000..a2395d9d7 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_0d2_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_0d6_states.bin.z b/client/hardnested/tables/bitflip_1_0d6_states.bin.z new file mode 100644 index 000000000..b2cc698ad Binary files /dev/null and b/client/hardnested/tables/bitflip_1_0d6_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_0d8_states.bin.z b/client/hardnested/tables/bitflip_1_0d8_states.bin.z new file mode 100644 index 000000000..4188dbd10 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_0d8_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_0da_states.bin.z b/client/hardnested/tables/bitflip_1_0da_states.bin.z new file mode 100644 index 000000000..f4115044a Binary files /dev/null and b/client/hardnested/tables/bitflip_1_0da_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_0de_states.bin.z b/client/hardnested/tables/bitflip_1_0de_states.bin.z new file mode 100644 index 000000000..42dfcc794 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_0de_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_0e0_states.bin.z b/client/hardnested/tables/bitflip_1_0e0_states.bin.z new file mode 100644 index 000000000..4af74d9a0 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_0e0_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_0e8_states.bin.z b/client/hardnested/tables/bitflip_1_0e8_states.bin.z new file mode 100644 index 000000000..4ff8482ff Binary files /dev/null and b/client/hardnested/tables/bitflip_1_0e8_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_0f8_states.bin.z b/client/hardnested/tables/bitflip_1_0f8_states.bin.z new file mode 100644 index 000000000..11466136f Binary files /dev/null and b/client/hardnested/tables/bitflip_1_0f8_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_108_states.bin.z b/client/hardnested/tables/bitflip_1_108_states.bin.z new file mode 100644 index 000000000..31234583d Binary files /dev/null and b/client/hardnested/tables/bitflip_1_108_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_111_states.bin.z b/client/hardnested/tables/bitflip_1_111_states.bin.z new file mode 100644 index 000000000..9840a5ebe Binary files /dev/null and b/client/hardnested/tables/bitflip_1_111_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_113_states.bin.z b/client/hardnested/tables/bitflip_1_113_states.bin.z new file mode 100644 index 000000000..9840a5ebe Binary files /dev/null and b/client/hardnested/tables/bitflip_1_113_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_115_states.bin.z b/client/hardnested/tables/bitflip_1_115_states.bin.z new file mode 100644 index 000000000..9840a5ebe Binary files /dev/null and b/client/hardnested/tables/bitflip_1_115_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_117_states.bin.z b/client/hardnested/tables/bitflip_1_117_states.bin.z new file mode 100644 index 000000000..9840a5ebe Binary files /dev/null and b/client/hardnested/tables/bitflip_1_117_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_118_states.bin.z b/client/hardnested/tables/bitflip_1_118_states.bin.z new file mode 100644 index 000000000..10afd75a4 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_118_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_11a_states.bin.z b/client/hardnested/tables/bitflip_1_11a_states.bin.z new file mode 100644 index 000000000..e0e985fcf Binary files /dev/null and b/client/hardnested/tables/bitflip_1_11a_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_11b_states.bin.z b/client/hardnested/tables/bitflip_1_11b_states.bin.z new file mode 100644 index 000000000..9840a5ebe Binary files /dev/null and b/client/hardnested/tables/bitflip_1_11b_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_120_states.bin.z b/client/hardnested/tables/bitflip_1_120_states.bin.z new file mode 100644 index 000000000..750af05d7 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_120_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_122_states.bin.z b/client/hardnested/tables/bitflip_1_122_states.bin.z new file mode 100644 index 000000000..6d04a3c05 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_122_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_128_states.bin.z b/client/hardnested/tables/bitflip_1_128_states.bin.z new file mode 100644 index 000000000..18d333145 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_128_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_131_states.bin.z b/client/hardnested/tables/bitflip_1_131_states.bin.z new file mode 100644 index 000000000..9840a5ebe Binary files /dev/null and b/client/hardnested/tables/bitflip_1_131_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_135_states.bin.z b/client/hardnested/tables/bitflip_1_135_states.bin.z new file mode 100644 index 000000000..9840a5ebe Binary files /dev/null and b/client/hardnested/tables/bitflip_1_135_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_138_states.bin.z b/client/hardnested/tables/bitflip_1_138_states.bin.z new file mode 100644 index 000000000..bc154b4f7 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_138_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_145_states.bin.z b/client/hardnested/tables/bitflip_1_145_states.bin.z new file mode 100644 index 000000000..9840a5ebe Binary files /dev/null and b/client/hardnested/tables/bitflip_1_145_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_147_states.bin.z b/client/hardnested/tables/bitflip_1_147_states.bin.z new file mode 100644 index 000000000..9840a5ebe Binary files /dev/null and b/client/hardnested/tables/bitflip_1_147_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_148_states.bin.z b/client/hardnested/tables/bitflip_1_148_states.bin.z new file mode 100644 index 000000000..ec5b774c7 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_148_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_158_states.bin.z b/client/hardnested/tables/bitflip_1_158_states.bin.z new file mode 100644 index 000000000..631b39af0 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_158_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_160_states.bin.z b/client/hardnested/tables/bitflip_1_160_states.bin.z new file mode 100644 index 000000000..32fb4f59a Binary files /dev/null and b/client/hardnested/tables/bitflip_1_160_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_161_states.bin.z b/client/hardnested/tables/bitflip_1_161_states.bin.z new file mode 100644 index 000000000..9840a5ebe Binary files /dev/null and b/client/hardnested/tables/bitflip_1_161_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_163_states.bin.z b/client/hardnested/tables/bitflip_1_163_states.bin.z new file mode 100644 index 000000000..9840a5ebe Binary files /dev/null and b/client/hardnested/tables/bitflip_1_163_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_165_states.bin.z b/client/hardnested/tables/bitflip_1_165_states.bin.z new file mode 100644 index 000000000..9840a5ebe Binary files /dev/null and b/client/hardnested/tables/bitflip_1_165_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_168_states.bin.z b/client/hardnested/tables/bitflip_1_168_states.bin.z new file mode 100644 index 000000000..af6bf431e Binary files /dev/null and b/client/hardnested/tables/bitflip_1_168_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_178_states.bin.z b/client/hardnested/tables/bitflip_1_178_states.bin.z new file mode 100644 index 000000000..17eec3aa5 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_178_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_180_states.bin.z b/client/hardnested/tables/bitflip_1_180_states.bin.z new file mode 100644 index 000000000..d3f655b04 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_180_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_188_states.bin.z b/client/hardnested/tables/bitflip_1_188_states.bin.z new file mode 100644 index 000000000..d5012b1d5 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_188_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_191_states.bin.z b/client/hardnested/tables/bitflip_1_191_states.bin.z new file mode 100644 index 000000000..9840a5ebe Binary files /dev/null and b/client/hardnested/tables/bitflip_1_191_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_198_states.bin.z b/client/hardnested/tables/bitflip_1_198_states.bin.z new file mode 100644 index 000000000..ca490c4fc Binary files /dev/null and b/client/hardnested/tables/bitflip_1_198_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_199_states.bin.z b/client/hardnested/tables/bitflip_1_199_states.bin.z new file mode 100644 index 000000000..9840a5ebe Binary files /dev/null and b/client/hardnested/tables/bitflip_1_199_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_19d_states.bin.z b/client/hardnested/tables/bitflip_1_19d_states.bin.z new file mode 100644 index 000000000..9840a5ebe Binary files /dev/null and b/client/hardnested/tables/bitflip_1_19d_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_19f_states.bin.z b/client/hardnested/tables/bitflip_1_19f_states.bin.z new file mode 100644 index 000000000..9840a5ebe Binary files /dev/null and b/client/hardnested/tables/bitflip_1_19f_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_1a0_states.bin.z b/client/hardnested/tables/bitflip_1_1a0_states.bin.z new file mode 100644 index 000000000..d6041407c Binary files /dev/null and b/client/hardnested/tables/bitflip_1_1a0_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_1a8_states.bin.z b/client/hardnested/tables/bitflip_1_1a8_states.bin.z new file mode 100644 index 000000000..10dd5e6b1 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_1a8_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_1b3_states.bin.z b/client/hardnested/tables/bitflip_1_1b3_states.bin.z new file mode 100644 index 000000000..9840a5ebe Binary files /dev/null and b/client/hardnested/tables/bitflip_1_1b3_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_1b5_states.bin.z b/client/hardnested/tables/bitflip_1_1b5_states.bin.z new file mode 100644 index 000000000..9840a5ebe Binary files /dev/null and b/client/hardnested/tables/bitflip_1_1b5_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_1b7_states.bin.z b/client/hardnested/tables/bitflip_1_1b7_states.bin.z new file mode 100644 index 000000000..9840a5ebe Binary files /dev/null and b/client/hardnested/tables/bitflip_1_1b7_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_1b8_states.bin.z b/client/hardnested/tables/bitflip_1_1b8_states.bin.z new file mode 100644 index 000000000..add474d02 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_1b8_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_1b9_states.bin.z b/client/hardnested/tables/bitflip_1_1b9_states.bin.z new file mode 100644 index 000000000..9840a5ebe Binary files /dev/null and b/client/hardnested/tables/bitflip_1_1b9_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_1bd_states.bin.z b/client/hardnested/tables/bitflip_1_1bd_states.bin.z new file mode 100644 index 000000000..9840a5ebe Binary files /dev/null and b/client/hardnested/tables/bitflip_1_1bd_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_1c1_states.bin.z b/client/hardnested/tables/bitflip_1_1c1_states.bin.z new file mode 100644 index 000000000..9840a5ebe Binary files /dev/null and b/client/hardnested/tables/bitflip_1_1c1_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_1c3_states.bin.z b/client/hardnested/tables/bitflip_1_1c3_states.bin.z new file mode 100644 index 000000000..9840a5ebe Binary files /dev/null and b/client/hardnested/tables/bitflip_1_1c3_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_1c8_states.bin.z b/client/hardnested/tables/bitflip_1_1c8_states.bin.z new file mode 100644 index 000000000..3a748e8d0 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_1c8_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_1c9_states.bin.z b/client/hardnested/tables/bitflip_1_1c9_states.bin.z new file mode 100644 index 000000000..9840a5ebe Binary files /dev/null and b/client/hardnested/tables/bitflip_1_1c9_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_1cd_states.bin.z b/client/hardnested/tables/bitflip_1_1cd_states.bin.z new file mode 100644 index 000000000..9840a5ebe Binary files /dev/null and b/client/hardnested/tables/bitflip_1_1cd_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_1cf_states.bin.z b/client/hardnested/tables/bitflip_1_1cf_states.bin.z new file mode 100644 index 000000000..9840a5ebe Binary files /dev/null and b/client/hardnested/tables/bitflip_1_1cf_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_1d8_states.bin.z b/client/hardnested/tables/bitflip_1_1d8_states.bin.z new file mode 100644 index 000000000..806157d21 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_1d8_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_1e0_states.bin.z b/client/hardnested/tables/bitflip_1_1e0_states.bin.z new file mode 100644 index 000000000..b7f699728 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_1e0_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_1e1_states.bin.z b/client/hardnested/tables/bitflip_1_1e1_states.bin.z new file mode 100644 index 000000000..9840a5ebe Binary files /dev/null and b/client/hardnested/tables/bitflip_1_1e1_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_1e5_states.bin.z b/client/hardnested/tables/bitflip_1_1e5_states.bin.z new file mode 100644 index 000000000..9840a5ebe Binary files /dev/null and b/client/hardnested/tables/bitflip_1_1e5_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_1e7_states.bin.z b/client/hardnested/tables/bitflip_1_1e7_states.bin.z new file mode 100644 index 000000000..9840a5ebe Binary files /dev/null and b/client/hardnested/tables/bitflip_1_1e7_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_1e8_states.bin.z b/client/hardnested/tables/bitflip_1_1e8_states.bin.z new file mode 100644 index 000000000..a68398e45 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_1e8_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_1e9_states.bin.z b/client/hardnested/tables/bitflip_1_1e9_states.bin.z new file mode 100644 index 000000000..9840a5ebe Binary files /dev/null and b/client/hardnested/tables/bitflip_1_1e9_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_1eb_states.bin.z b/client/hardnested/tables/bitflip_1_1eb_states.bin.z new file mode 100644 index 000000000..9840a5ebe Binary files /dev/null and b/client/hardnested/tables/bitflip_1_1eb_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_1ed_states.bin.z b/client/hardnested/tables/bitflip_1_1ed_states.bin.z new file mode 100644 index 000000000..9840a5ebe Binary files /dev/null and b/client/hardnested/tables/bitflip_1_1ed_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_1f8_states.bin.z b/client/hardnested/tables/bitflip_1_1f8_states.bin.z new file mode 100644 index 000000000..dc0f16fc4 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_1f8_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_208_states.bin.z b/client/hardnested/tables/bitflip_1_208_states.bin.z new file mode 100644 index 000000000..c8a8cf4a0 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_208_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_220_states.bin.z b/client/hardnested/tables/bitflip_1_220_states.bin.z new file mode 100644 index 000000000..479bacb03 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_220_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_24a_states.bin.z b/client/hardnested/tables/bitflip_1_24a_states.bin.z new file mode 100644 index 000000000..a4cc5d58c Binary files /dev/null and b/client/hardnested/tables/bitflip_1_24a_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_24e_states.bin.z b/client/hardnested/tables/bitflip_1_24e_states.bin.z new file mode 100644 index 000000000..f7bb63eb7 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_24e_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_25a_states.bin.z b/client/hardnested/tables/bitflip_1_25a_states.bin.z new file mode 100644 index 000000000..4e5b2ff27 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_25a_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_25e_states.bin.z b/client/hardnested/tables/bitflip_1_25e_states.bin.z new file mode 100644 index 000000000..f8686dba6 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_25e_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_262_states.bin.z b/client/hardnested/tables/bitflip_1_262_states.bin.z new file mode 100644 index 000000000..a4cc5d58c Binary files /dev/null and b/client/hardnested/tables/bitflip_1_262_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_266_states.bin.z b/client/hardnested/tables/bitflip_1_266_states.bin.z new file mode 100644 index 000000000..f7bb63eb7 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_266_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_272_states.bin.z b/client/hardnested/tables/bitflip_1_272_states.bin.z new file mode 100644 index 000000000..4e5b2ff27 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_272_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_276_states.bin.z b/client/hardnested/tables/bitflip_1_276_states.bin.z new file mode 100644 index 000000000..f8686dba6 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_276_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_280_states.bin.z b/client/hardnested/tables/bitflip_1_280_states.bin.z new file mode 100644 index 000000000..e4f4b6ac6 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_280_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_2a8_states.bin.z b/client/hardnested/tables/bitflip_1_2a8_states.bin.z new file mode 100644 index 000000000..c8a8cf4a0 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_2a8_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_2c2_states.bin.z b/client/hardnested/tables/bitflip_1_2c2_states.bin.z new file mode 100644 index 000000000..a4cc5d58c Binary files /dev/null and b/client/hardnested/tables/bitflip_1_2c2_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_2c6_states.bin.z b/client/hardnested/tables/bitflip_1_2c6_states.bin.z new file mode 100644 index 000000000..f7bb63eb7 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_2c6_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_2d2_states.bin.z b/client/hardnested/tables/bitflip_1_2d2_states.bin.z new file mode 100644 index 000000000..4e5b2ff27 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_2d2_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_2d6_states.bin.z b/client/hardnested/tables/bitflip_1_2d6_states.bin.z new file mode 100644 index 000000000..f8686dba6 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_2d6_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_328_states.bin.z b/client/hardnested/tables/bitflip_1_328_states.bin.z new file mode 100644 index 000000000..c8a8cf4a0 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_328_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_388_states.bin.z b/client/hardnested/tables/bitflip_1_388_states.bin.z new file mode 100644 index 000000000..c8a8cf4a0 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_388_states.bin.z differ diff --git a/client/hardnested/tables/bitflip_1_3a0_states.bin.z b/client/hardnested/tables/bitflip_1_3a0_states.bin.z new file mode 100644 index 000000000..479bacb03 Binary files /dev/null and b/client/hardnested/tables/bitflip_1_3a0_states.bin.z differ diff --git a/client/mfkey.c b/client/mfkey.c new file mode 100644 index 000000000..a1fdbba1f --- /dev/null +++ b/client/mfkey.c @@ -0,0 +1,96 @@ +//----------------------------------------------------------------------------- +// Merlok - June 2011 +// Roel - Dec 2009 +// Unknown author +// +// 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. +//----------------------------------------------------------------------------- +// MIFARE Darkside hack +//----------------------------------------------------------------------------- +#include "mfkey.h" +#include "crapto1/crapto1.h" + +// recover key from 2 different reader responses on same tag challenge +bool mfkey32(nonces_t data, uint64_t *outputkey) { + struct Crypto1State *s,*t; + uint64_t outkey = 0; + uint64_t key = 0; // recovered key + bool isSuccess = false; + uint8_t counter = 0; + + s = lfsr_recovery32(data.ar ^ prng_successor(data.nonce, 64), 0); + + for(t = s; t->odd | t->even; ++t) { + lfsr_rollback_word(t, 0, 0); + lfsr_rollback_word(t, data.nr, 1); + lfsr_rollback_word(t, data.cuid ^ data.nonce, 0); + crypto1_get_lfsr(t, &key); + crypto1_word(t, data.cuid ^ data.nonce, 0); + crypto1_word(t, data.nr2, 1); + if (data.ar2 == (crypto1_word(t, 0, 0) ^ prng_successor(data.nonce, 64))) { + outkey = key; + counter++; + if (counter == 20) break; + } + } + isSuccess = (counter == 1); + *outputkey = ( isSuccess ) ? outkey : 0; + crypto1_destroy(s); + return isSuccess; +} + +// recover key from 2 reader responses on 2 different tag challenges +bool mfkey32_moebius(nonces_t data, uint64_t *outputkey) { + struct Crypto1State *s, *t; + uint64_t outkey = 0; + uint64_t key = 0; // recovered key + bool isSuccess = false; + int counter = 0; + + s = lfsr_recovery32(data.ar ^ prng_successor(data.nonce, 64), 0); + + for(t = s; t->odd | t->even; ++t) { + lfsr_rollback_word(t, 0, 0); + lfsr_rollback_word(t, data.nr, 1); + lfsr_rollback_word(t, data.cuid ^ data.nonce, 0); + crypto1_get_lfsr(t, &key); + + crypto1_word(t, data.cuid ^ data.nonce2, 0); + crypto1_word(t, data.nr2, 1); + if (data.ar2 == (crypto1_word(t, 0, 0) ^ prng_successor(data.nonce2, 64))) { + outkey=key; + ++counter; + if (counter==20) + break; + } + } + isSuccess = (counter == 1); + *outputkey = ( isSuccess ) ? outkey : 0; + crypto1_destroy(s); + return isSuccess; +} + +// recover key from reader response and tag response of one authentication sequence +int mfkey64(nonces_t data, uint64_t *outputkey){ + uint64_t key = 0; // recovered key + uint32_t ks2; // keystream used to encrypt reader response + uint32_t ks3; // keystream used to encrypt tag response + struct Crypto1State *revstate; + + // Extract the keystream from the messages + ks2 = data.ar ^ prng_successor(data.nonce, 64); + ks3 = data.at ^ prng_successor(data.nonce, 96); + revstate = lfsr_recovery64(ks2, ks3); + lfsr_rollback_word(revstate, 0, 0); + lfsr_rollback_word(revstate, 0, 0); + lfsr_rollback_word(revstate, data.nr, 1); + lfsr_rollback_word(revstate, data.cuid ^ data.nonce, 0); + crypto1_get_lfsr(revstate, &key); + crypto1_destroy(revstate); + *outputkey = key; + return 0; +} + + diff --git a/client/mfkey.h b/client/mfkey.h new file mode 100644 index 000000000..be32fe1bd --- /dev/null +++ b/client/mfkey.h @@ -0,0 +1,24 @@ +//----------------------------------------------------------------------------- +// Merlok - June 2011 +// Roel - Dec 2009 +// Unknown author +// +// 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. +//----------------------------------------------------------------------------- +// MIFARE Darkside hack +//----------------------------------------------------------------------------- + +#ifndef MFKEY_H +#define MFKEY_H + +#include +#include +#include "mifare.h" + +extern bool mfkey32(nonces_t data, uint64_t *outputkey); +extern bool mfkey32_moebius(nonces_t data, uint64_t *outputkey); +extern int mfkey64(nonces_t data, uint64_t *outputkey); + +#endif diff --git a/client/usb_cmd_h2lua.awk b/client/usb_cmd_h2lua.awk new file mode 100644 index 000000000..8e003562a --- /dev/null +++ b/client/usb_cmd_h2lua.awk @@ -0,0 +1,15 @@ +BEGIN { + print "--[[" + print "These are Proxmark command definitions." + print "This file is automatically generated from usb_cmd.h - DON'T EDIT MANUALLY." + print "--]]" + print "local __commands = {" +} + +#$1 ~ /#define/ && $2 ~ /^CMD_([[:alnum:]_])+/ { print $2, "=", $3, "," } +$1 ~ /#define/ && $2 ~ /^CMD_[A-Za-z0-9_]+/ { sub(/\r/, ""); print $2, "=", $3 "," } + +END { + print "}" + print "return __commands" +} diff --git a/client/util_posix.c b/client/util_posix.c new file mode 100644 index 000000000..dd3d714c5 --- /dev/null +++ b/client/util_posix.c @@ -0,0 +1,133 @@ +//----------------------------------------------------------------------------- +// Copyright (C) 2010 iZsh +// +// 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. +//----------------------------------------------------------------------------- +// utilities requiring Posix library functions +//----------------------------------------------------------------------------- + +#if !defined(_WIN32) +#define _POSIX_C_SOURCE 199309L // need nanosleep() +#else +#include +#endif + +#include "util_posix.h" +#include +#include + + +// Timer functions +#if !defined (_WIN32) +#include + +static void nsleep(uint64_t n) { + struct timespec timeout; + timeout.tv_sec = n/1000000000; + timeout.tv_nsec = n%1000000000; + while (nanosleep(&timeout, &timeout) && errno == EINTR); +} + +void msleep(uint32_t n) { + nsleep(1000000 * (uint64_t)n); +} +#endif // _WIN32 + +#ifdef __MACH__ + + #define CLOCK_MONOTONIC (1) + #define CLOCK_REALTIME (2) + + #include + #include + #include + #include + + /* clock_gettime is not implemented on OSX prior to 10.12 */ + int _civet_clock_gettime(int clk_id, struct timespec *t); + + int _civet_clock_gettime(int clk_id, struct timespec *t) + { + memset(t, 0, sizeof(*t)); + if (clk_id == CLOCK_REALTIME) { + struct timeval now; + int rv = gettimeofday(&now, NULL); + if (rv) { + return rv; + } + t->tv_sec = now.tv_sec; + t->tv_nsec = now.tv_usec * 1000; + return 0; + + } else if (clk_id == CLOCK_MONOTONIC) { + static uint64_t clock_start_time = 0; + static mach_timebase_info_data_t timebase_ifo = {0, 0}; + + uint64_t now = mach_absolute_time(); + + if (clock_start_time == 0) { + //kern_return_t mach_status = mach_timebase_info(&timebase_ifo); + // appease "unused variable" warning for release builds + //(void)mach_status; + clock_start_time = now; + } + + now = (uint64_t)((double)(now - clock_start_time) + * (double)timebase_ifo.numer + / (double)timebase_ifo.denom); + + t->tv_sec = now / 1000000000; + t->tv_nsec = now % 1000000000; + return 0; + } + return -1; // EINVAL - Clock ID is unknown + } + + /* if clock_gettime is declared, then __CLOCK_AVAILABILITY will be defined */ + #ifdef __CLOCK_AVAILABILITY + /* If we compiled with Mac OSX 10.12 or later, then clock_gettime will be declared + * but it may be NULL at runtime. So we need to check before using it. */ + int _civet_safe_clock_gettime(int clk_id, struct timespec *t); + + int _civet_safe_clock_gettime(int clk_id, struct timespec *t) { + if( clock_gettime ) { + return clock_gettime(clk_id, t); + } + return _civet_clock_gettime(clk_id, t); + } + #define clock_gettime _civet_safe_clock_gettime + #else + #define clock_gettime _civet_clock_gettime + #endif + +#endif + + +// a milliseconds timer for performance measurement +uint64_t msclock() { +#if defined(_WIN32) + #include + + // WORKAROUND FOR MinGW (some versions - use if normal code does not compile) + // It has no _ftime_s and needs explicit inclusion of timeb.h + #include + struct _timeb t; + _ftime(&t); + return 1000 * t.time + t.millitm; + +// NORMAL CODE (use _ftime_s) + //struct _timeb t; + //if (_ftime_s(&t)) { + // return 0; + //} else { + // return 1000 * t.time + t.millitm; + //} +#else + struct timespec t; + clock_gettime(CLOCK_MONOTONIC, &t); + return (t.tv_sec * 1000 + t.tv_nsec / 1000000); +#endif +} + diff --git a/client/util_posix.h b/client/util_posix.h new file mode 100644 index 000000000..dcf9d99aa --- /dev/null +++ b/client/util_posix.h @@ -0,0 +1,26 @@ +//----------------------------------------------------------------------------- +// Copyright (C) 2010 iZsh +// +// 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. +//----------------------------------------------------------------------------- +// utilities requiring Posix library functions +//----------------------------------------------------------------------------- + +#ifndef UTIL_POSIX_H__ +#define UTIL_POSIX_H__ + +#include + +#ifdef _WIN32 +# include +# define sleep(n) Sleep(1000 *(n)) +# define msleep(n) Sleep((n)) +#else +extern void msleep(uint32_t n); // sleep n milliseconds +#endif // _WIN32 + +extern uint64_t msclock(); // a milliseconds clock + +#endif diff --git a/common/crapto1/crapto1.c b/common/crapto1/crapto1.c new file mode 100644 index 000000000..54fbbbff1 --- /dev/null +++ b/common/crapto1/crapto1.c @@ -0,0 +1,556 @@ +/* crapto1.c + + 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 2 + 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. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, US$ + + Copyright (C) 2008-2014 bla +*/ +#include "crapto1.h" + +#include +#include "parity.h" + +#if !defined LOWMEM && defined __GNUC__ +static uint8_t filterlut[1 << 20]; +static void __attribute__((constructor)) fill_lut() +{ + uint32_t i; + for(i = 0; i < 1 << 20; ++i) + filterlut[i] = filter(i); +} +#define filter(x) (filterlut[(x) & 0xfffff]) +#endif + + + +typedef struct bucket { + uint32_t *head; + uint32_t *bp; +} bucket_t; + +typedef bucket_t bucket_array_t[2][0x100]; + +typedef struct bucket_info { + struct { + uint32_t *head, *tail; + } bucket_info[2][0x100]; + uint32_t numbuckets; + } bucket_info_t; + + +static void bucket_sort_intersect(uint32_t* const estart, uint32_t* const estop, + uint32_t* const ostart, uint32_t* const ostop, + bucket_info_t *bucket_info, bucket_array_t bucket) +{ + uint32_t *p1, *p2; + uint32_t *start[2]; + uint32_t *stop[2]; + + start[0] = estart; + stop[0] = estop; + start[1] = ostart; + stop[1] = ostop; + + // init buckets to be empty + for (uint32_t i = 0; i < 2; i++) { + for (uint32_t j = 0x00; j <= 0xff; j++) { + bucket[i][j].bp = bucket[i][j].head; + } + } + + // sort the lists into the buckets based on the MSB (contribution bits) + for (uint32_t i = 0; i < 2; i++) { + for (p1 = start[i]; p1 <= stop[i]; p1++) { + uint32_t bucket_index = (*p1 & 0xff000000) >> 24; + *(bucket[i][bucket_index].bp++) = *p1; + } + } + + + // write back intersecting buckets as sorted list. + // fill in bucket_info with head and tail of the bucket contents in the list and number of non-empty buckets. + uint32_t nonempty_bucket; + for (uint32_t i = 0; i < 2; i++) { + p1 = start[i]; + nonempty_bucket = 0; + for (uint32_t j = 0x00; j <= 0xff; j++) { + if (bucket[0][j].bp != bucket[0][j].head && bucket[1][j].bp != bucket[1][j].head) { // non-empty intersecting buckets only + bucket_info->bucket_info[i][nonempty_bucket].head = p1; + for (p2 = bucket[i][j].head; p2 < bucket[i][j].bp; *p1++ = *p2++); + bucket_info->bucket_info[i][nonempty_bucket].tail = p1 - 1; + nonempty_bucket++; + } + } + bucket_info->numbuckets = nonempty_bucket; + } +} +/** binsearch + * Binary search for the first occurence of *stop's MSB in sorted [start,stop] + */ +/* static inline uint32_t* binsearch(uint32_t *start, uint32_t *stop) +{ + uint32_t mid, val = *stop & 0xff000000; + while(start != stop) + if(start[mid = (stop - start) >> 1] > val) + stop = &start[mid]; + else + start += mid + 1; + + return start; +} + */ +/** update_contribution + * helper, calculates the partial linear feedback contributions and puts in MSB + */ +static inline void update_contribution(uint32_t *item, const uint32_t mask1, const uint32_t mask2) +{ + uint32_t p = *item >> 25; + + p = p << 1 | evenparity32(*item & mask1); + p = p << 1 | evenparity32(*item & mask2); + *item = p << 24 | (*item & 0xffffff); +} + +/** extend_table + * using a bit of the keystream extend the table of possible lfsr states + */ +static inline void extend_table(uint32_t *tbl, uint32_t **end, int bit, int m1, int m2, uint32_t in) +{ + in <<= 24; + for(*tbl <<= 1; tbl <= *end; *++tbl <<= 1) + if(filter(*tbl) ^ filter(*tbl | 1)) { + *tbl |= filter(*tbl) ^ bit; + update_contribution(tbl, m1, m2); + *tbl ^= in; + } else if(filter(*tbl) == bit) { + *++*end = tbl[1]; + tbl[1] = tbl[0] | 1; + update_contribution(tbl, m1, m2); + *tbl++ ^= in; + update_contribution(tbl, m1, m2); + *tbl ^= in; + } else + *tbl-- = *(*end)--; +} +/** extend_table_simple + * using a bit of the keystream extend the table of possible lfsr states + */ +static inline void extend_table_simple(uint32_t *tbl, uint32_t **end, int bit) +{ + for(*tbl <<= 1; tbl <= *end; *++tbl <<= 1) { + if(filter(*tbl) ^ filter(*tbl | 1)) { // replace + *tbl |= filter(*tbl) ^ bit; + } else if(filter(*tbl) == bit) { // insert + *++*end = *++tbl; + *tbl = tbl[-1] | 1; + } else { // drop + *tbl-- = *(*end)--; +} + } +} +/** recover + * recursively narrow down the search space, 4 bits of keystream at a time + */ +static struct Crypto1State* +recover(uint32_t *o_head, uint32_t *o_tail, uint32_t oks, + uint32_t *e_head, uint32_t *e_tail, uint32_t eks, int rem, + struct Crypto1State *sl, uint32_t in, bucket_array_t bucket) +{ + uint32_t *o, *e; + bucket_info_t bucket_info; + + if(rem == -1) { + for(e = e_head; e <= e_tail; ++e) { + *e = *e << 1 ^ evenparity32(*e & LF_POLY_EVEN) ^ !!(in & 4); + for(o = o_head; o <= o_tail; ++o, ++sl) { + sl->even = *o; + sl->odd = *e ^ evenparity32(*o & LF_POLY_ODD); + sl[1].odd = sl[1].even = 0; + } + } + return sl; + } + + for(uint32_t i = 0; i < 4 && rem--; i++) { + oks >>= 1; + eks >>= 1; + in >>= 2; + extend_table(o_head, &o_tail, oks & 1, LF_POLY_EVEN << 1 | 1, LF_POLY_ODD << 1, 0); + if(o_head > o_tail) + return sl; + + extend_table(e_head, &e_tail, eks & 1, LF_POLY_ODD, LF_POLY_EVEN << 1 | 1, in & 3); + if(e_head > e_tail) + return sl; + } + + bucket_sort_intersect(e_head, e_tail, o_head, o_tail, &bucket_info, bucket); + + for (int i = bucket_info.numbuckets - 1; i >= 0; i--) { + sl = recover(bucket_info.bucket_info[1][i].head, bucket_info.bucket_info[1][i].tail, oks, + bucket_info.bucket_info[0][i].head, bucket_info.bucket_info[0][i].tail, eks, + rem, sl, in, bucket); + } + + return sl; +} +/** lfsr_recovery + * recover the state of the lfsr given 32 bits of the keystream + * additionally you can use the in parameter to specify the value + * that was fed into the lfsr at the time the keystream was generated + */ +struct Crypto1State* lfsr_recovery32(uint32_t ks2, uint32_t in) +{ + struct Crypto1State *statelist; + uint32_t *odd_head = 0, *odd_tail = 0, oks = 0; + uint32_t *even_head = 0, *even_tail = 0, eks = 0; + int i; + + // split the keystream into an odd and even part + for(i = 31; i >= 0; i -= 2) + oks = oks << 1 | BEBIT(ks2, i); + for(i = 30; i >= 0; i -= 2) + eks = eks << 1 | BEBIT(ks2, i); + + odd_head = odd_tail = malloc(sizeof(uint32_t) << 21); + even_head = even_tail = malloc(sizeof(uint32_t) << 21); + statelist = malloc(sizeof(struct Crypto1State) << 18); + if(!odd_tail-- || !even_tail-- || !statelist) { + free(statelist); + statelist = 0; + goto out; + } + + statelist->odd = statelist->even = 0; + + // allocate memory for out of place bucket_sort + bucket_array_t bucket; + + for (uint32_t i = 0; i < 2; i++) { + for (uint32_t j = 0; j <= 0xff; j++) { + bucket[i][j].head = malloc(sizeof(uint32_t)<<14); + if (!bucket[i][j].head) { + goto out; + } + } + } + + // initialize statelists: add all possible states which would result into the rightmost 2 bits of the keystream + for(i = 1 << 20; i >= 0; --i) { + if(filter(i) == (oks & 1)) + *++odd_tail = i; + if(filter(i) == (eks & 1)) + *++even_tail = i; + } + + // extend the statelists. Look at the next 8 Bits of the keystream (4 Bit each odd and even): + for(i = 0; i < 4; i++) { + extend_table_simple(odd_head, &odd_tail, (oks >>= 1) & 1); + extend_table_simple(even_head, &even_tail, (eks >>= 1) & 1); + } + + // the statelists now contain all states which could have generated the last 10 Bits of the keystream. + // 22 bits to go to recover 32 bits in total. From now on, we need to take the "in" + // parameter into account. + in = (in >> 16 & 0xff) | (in << 16) | (in & 0xff00); // Byte swapping + recover(odd_head, odd_tail, oks, even_head, even_tail, eks, 11, statelist, in << 1, bucket); + +out: + free(odd_head); + free(even_head); + for (uint32_t i = 0; i < 2; i++) + for (uint32_t j = 0; j <= 0xff; j++) + free(bucket[i][j].head); + + return statelist; +} + +static const uint32_t S1[] = { 0x62141, 0x310A0, 0x18850, 0x0C428, 0x06214, + 0x0310A, 0x85E30, 0xC69AD, 0x634D6, 0xB5CDE, 0xDE8DA, 0x6F46D, 0xB3C83, + 0x59E41, 0xA8995, 0xD027F, 0x6813F, 0x3409F, 0x9E6FA}; +static const uint32_t S2[] = { 0x3A557B00, 0x5D2ABD80, 0x2E955EC0, 0x174AAF60, + 0x0BA557B0, 0x05D2ABD8, 0x0449DE68, 0x048464B0, 0x42423258, 0x278192A8, + 0x156042D0, 0x0AB02168, 0x43F89B30, 0x61FC4D98, 0x765EAD48, 0x7D8FDD20, + 0x7EC7EE90, 0x7F63F748, 0x79117020}; +static const uint32_t T1[] = { + 0x4F37D, 0x279BE, 0x97A6A, 0x4BD35, 0x25E9A, 0x12F4D, 0x097A6, 0x80D66, + 0xC4006, 0x62003, 0xB56B4, 0x5AB5A, 0xA9318, 0xD0F39, 0x6879C, 0xB057B, + 0x582BD, 0x2C15E, 0x160AF, 0x8F6E2, 0xC3DC4, 0xE5857, 0x72C2B, 0x39615, + 0x98DBF, 0xC806A, 0xE0680, 0x70340, 0x381A0, 0x98665, 0x4C332, 0xA272C}; +static const uint32_t T2[] = { 0x3C88B810, 0x5E445C08, 0x2982A580, 0x14C152C0, + 0x4A60A960, 0x253054B0, 0x52982A58, 0x2FEC9EA8, 0x1156C4D0, 0x08AB6268, + 0x42F53AB0, 0x217A9D58, 0x161DC528, 0x0DAE6910, 0x46D73488, 0x25CB11C0, + 0x52E588E0, 0x6972C470, 0x34B96238, 0x5CFC3A98, 0x28DE96C8, 0x12CFC0E0, + 0x4967E070, 0x64B3F038, 0x74F97398, 0x7CDC3248, 0x38CE92A0, 0x1C674950, + 0x0E33A4A8, 0x01B959D0, 0x40DCACE8, 0x26CEDDF0}; +static const uint32_t C1[] = { 0x846B5, 0x4235A, 0x211AD}; +static const uint32_t C2[] = { 0x1A822E0, 0x21A822E0, 0x21A822E0}; +/** Reverse 64 bits of keystream into possible cipher states + * Variation mentioned in the paper. Somewhat optimized version + */ +struct Crypto1State* lfsr_recovery64(uint32_t ks2, uint32_t ks3) +{ + struct Crypto1State *statelist, *sl; + uint8_t oks[32], eks[32], hi[32]; + uint32_t low = 0, win = 0; + uint32_t *tail, table[1 << 16]; + int i, j; + + sl = statelist = malloc(sizeof(struct Crypto1State) << 4); + if(!sl) + return 0; + sl->odd = sl->even = 0; + + for(i = 30; i >= 0; i -= 2) { + oks[i >> 1] = BEBIT(ks2, i); + oks[16 + (i >> 1)] = BEBIT(ks3, i); + } + for(i = 31; i >= 0; i -= 2) { + eks[i >> 1] = BEBIT(ks2, i); + eks[16 + (i >> 1)] = BEBIT(ks3, i); + } + + for(i = 0xfffff; i >= 0; --i) { + if (filter(i) != oks[0]) + continue; + + *(tail = table) = i; + for(j = 1; tail >= table && j < 29; ++j) + extend_table_simple(table, &tail, oks[j]); + + if(tail < table) + continue; + + for(j = 0; j < 19; ++j) + low = low << 1 | evenparity32(i & S1[j]); + for(j = 0; j < 32; ++j) + hi[j] = evenparity32(i & T1[j]); + + for(; tail >= table; --tail) { + for(j = 0; j < 3; ++j) { + *tail = *tail << 1; + *tail |= evenparity32((i & C1[j]) ^ (*tail & C2[j])); + if(filter(*tail) != oks[29 + j]) + goto continue2; + } + + for(j = 0; j < 19; ++j) + win = win << 1 | evenparity32(*tail & S2[j]); + + win ^= low; + for(j = 0; j < 32; ++j) { + win = win << 1 ^ hi[j] ^ evenparity32(*tail & T2[j]); + if(filter(win) != eks[j]) + goto continue2; + } + + *tail = *tail << 1 | evenparity32(LF_POLY_EVEN & *tail); + sl->odd = *tail ^ evenparity32(LF_POLY_ODD & win); + sl->even = win; + ++sl; + sl->odd = sl->even = 0; + continue2:; + } + } + return statelist; +} + +/** lfsr_rollback_bit + * Rollback the shift register in order to get previous states + */ +uint8_t lfsr_rollback_bit(struct Crypto1State *s, uint32_t in, int fb) +{ + int out; + uint8_t ret; + uint32_t t; + + s->odd &= 0xffffff; + t = s->odd, s->odd = s->even, s->even = t; + + out = s->even & 1; + out ^= LF_POLY_EVEN & (s->even >>= 1); + out ^= LF_POLY_ODD & s->odd; + out ^= !!in; + out ^= (ret = filter(s->odd)) & !!fb; + + s->even |= evenparity32(out) << 23; + return ret; +} +/** lfsr_rollback_byte + * Rollback the shift register in order to get previous states + */ +uint8_t lfsr_rollback_byte(struct Crypto1State *s, uint32_t in, int fb) +{ + int i, ret=0; + for (i = 7; i >= 0; --i) + ret |= lfsr_rollback_bit(s, BIT(in, i), fb) << i; + return ret; +} +/** lfsr_rollback_word + * Rollback the shift register in order to get previous states + */ +uint32_t lfsr_rollback_word(struct Crypto1State *s, uint32_t in, int fb) +{ + int i; + uint32_t ret = 0; + for (i = 31; i >= 0; --i) + ret |= lfsr_rollback_bit(s, BEBIT(in, i), fb) << (i ^ 24); + return ret; +} + +/** nonce_distance + * x,y valid tag nonces, then prng_successor(x, nonce_distance(x, y)) = y + */ +static uint16_t *dist = 0; +int nonce_distance(uint32_t from, uint32_t to) +{ + uint16_t x, i; + if(!dist) { + dist = malloc(2 << 16); + if(!dist) + return -1; + for (x = i = 1; i; ++i) { + dist[(x & 0xff) << 8 | x >> 8] = i; + x = x >> 1 | (x ^ x >> 2 ^ x >> 3 ^ x >> 5) << 15; + } + } + return (65535 + dist[to >> 16] - dist[from >> 16]) % 65535; +} + +/** validate_prng_nonce + * Determine if nonce is deterministic. ie: Suspectable to Darkside attack. + * returns + * true = weak prng + * false = hardend prng + */ +bool validate_prng_nonce(uint32_t nonce) { + // init prng table: + nonce_distance(nonce, nonce); + return ((65535 - dist[nonce >> 16] + dist[nonce & 0xffff]) % 65535) == 16; +} + +static uint32_t fastfwd[2][8] = { + { 0, 0x4BC53, 0xECB1, 0x450E2, 0x25E29, 0x6E27A, 0x2B298, 0x60ECB}, + { 0, 0x1D962, 0x4BC53, 0x56531, 0xECB1, 0x135D3, 0x450E2, 0x58980}}; + + +/** lfsr_prefix_ks + * + * Is an exported helper function from the common prefix attack + * Described in the "dark side" paper. It returns an -1 terminated array + * of possible partial(21 bit) secret state. + * The required keystream(ks) needs to contain the keystream that was used to + * encrypt the NACK which is observed when varying only the 3 last bits of Nr + * only correct iff [NR_3] ^ NR_3 does not depend on Nr_3 + */ +uint32_t *lfsr_prefix_ks(uint8_t ks[8], int isodd) +{ + uint32_t *candidates = malloc(4 << 10); + if(!candidates) return 0; + + uint32_t c, entry; + int size = 0, i, good; + + for(i = 0; i < 1 << 21; ++i) { + for(c = 0, good = 1; good && c < 8; ++c) { + entry = i ^ fastfwd[isodd][c]; + good &= (BIT(ks[c], isodd) == filter(entry >> 1)); + good &= (BIT(ks[c], isodd + 2) == filter(entry)); + } + if(good) + candidates[size++] = i; + } + + candidates[size] = -1; + + return candidates; +} + +/** check_pfx_parity + * helper function which eliminates possible secret states using parity bits + */ +static struct Crypto1State* +check_pfx_parity(uint32_t prefix, uint32_t rresp, uint8_t parities[8][8], + uint32_t odd, uint32_t even, struct Crypto1State* sl, uint32_t no_par) +{ + uint32_t ks1, nr, ks2, rr, ks3, c, good = 1; + + for(c = 0; good && c < 8; ++c) { + sl->odd = odd ^ fastfwd[1][c]; + sl->even = even ^ fastfwd[0][c]; + + lfsr_rollback_bit(sl, 0, 0); + lfsr_rollback_bit(sl, 0, 0); + + ks3 = lfsr_rollback_bit(sl, 0, 0); + ks2 = lfsr_rollback_word(sl, 0, 0); + ks1 = lfsr_rollback_word(sl, prefix | c << 5, 1); + + if (no_par) + break; + + nr = ks1 ^ (prefix | c << 5); + rr = ks2 ^ rresp; + + good &= evenparity32(nr & 0x000000ff) ^ parities[c][3] ^ BIT(ks2, 24); + good &= evenparity32(rr & 0xff000000) ^ parities[c][4] ^ BIT(ks2, 16); + good &= evenparity32(rr & 0x00ff0000) ^ parities[c][5] ^ BIT(ks2, 8); + good &= evenparity32(rr & 0x0000ff00) ^ parities[c][6] ^ BIT(ks2, 0); + good &= evenparity32(rr & 0x000000ff) ^ parities[c][7] ^ ks3; + } + + return sl + good; +} + + +/** lfsr_common_prefix + * Implentation of the common prefix attack. + * Requires the 28 bit constant prefix used as reader nonce (pfx) + * The reader response used (rr) + * The keystream used to encrypt the observed NACK's (ks) + * The parity bits (par) + * It returns a zero terminated list of possible cipher states after the + * tag nonce was fed in + */ +struct Crypto1State* +lfsr_common_prefix(uint32_t pfx, uint32_t rr, uint8_t ks[8], uint8_t par[8][8], uint32_t no_par) +{ + struct Crypto1State *statelist, *s; + uint32_t *odd, *even, *o, *e, top; + + odd = lfsr_prefix_ks(ks, 1); + even = lfsr_prefix_ks(ks, 0); + + s = statelist = malloc((sizeof *statelist) << 24); // was << 20. Need more for no_par special attack. Enough??? + if(!s || !odd || !even) { + free(statelist); + statelist = 0; + goto out; + } + + for(o = odd; *o + 1; ++o) + for(e = even; *e + 1; ++e) + for(top = 0; top < 64; ++top) { + *o += 1 << 21; + *e += (!(top & 7) + 1) << 21; + s = check_pfx_parity(pfx, rr, par, *o, *e, s, no_par); + } + + s->odd = s->even = 0; +out: + free(odd); + free(even); + return statelist; +} diff --git a/common/crapto1/crapto1.h b/common/crapto1/crapto1.h new file mode 100644 index 000000000..154e4cc8a --- /dev/null +++ b/common/crapto1/crapto1.h @@ -0,0 +1,82 @@ +/* crapto1.h + + 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 2 + 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. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, US$ + + Copyright (C) 2008-2014 bla +*/ +#ifndef CRAPTO1_INCLUDED +#define CRAPTO1_INCLUDED +#include +#include +#ifdef __cplusplus +extern "C" { +#endif + +struct Crypto1State {uint32_t odd, even;}; +#if defined(__arm__) && !defined(__linux__) && !defined(_WIN32) && !defined(__APPLE__) // bare metal ARM Proxmark lacks malloc()/free() +void crypto1_create(struct Crypto1State *s, uint64_t key); +#else +struct Crypto1State *crypto1_create(uint64_t key); +#endif +void crypto1_destroy(struct Crypto1State*); +void crypto1_get_lfsr(struct Crypto1State*, uint64_t*); +uint8_t crypto1_bit(struct Crypto1State*, uint8_t, int); +uint8_t crypto1_byte(struct Crypto1State*, uint8_t, int); +uint32_t crypto1_word(struct Crypto1State*, uint32_t, int); +uint32_t prng_successor(uint32_t x, uint32_t n); + +struct Crypto1State* lfsr_recovery32(uint32_t ks2, uint32_t in); +struct Crypto1State* lfsr_recovery64(uint32_t ks2, uint32_t ks3); +uint32_t *lfsr_prefix_ks(uint8_t ks[8], int isodd); +struct Crypto1State* +lfsr_common_prefix(uint32_t pfx, uint32_t rr, uint8_t ks[8], uint8_t par[8][8], uint32_t no_par); + + +uint8_t lfsr_rollback_bit(struct Crypto1State* s, uint32_t in, int fb); +uint8_t lfsr_rollback_byte(struct Crypto1State* s, uint32_t in, int fb); +uint32_t lfsr_rollback_word(struct Crypto1State* s, uint32_t in, int fb); +int nonce_distance(uint32_t from, uint32_t to); +extern bool validate_prng_nonce(uint32_t nonce); +#define FOREACH_VALID_NONCE(N, FILTER, FSIZE)\ + uint32_t __n = 0,__M = 0, N = 0;\ + int __i;\ + for(; __n < 1 << 16; N = prng_successor(__M = ++__n, 16))\ + for(__i = FSIZE - 1; __i >= 0; __i--)\ + if(BIT(FILTER, __i) ^ evenparity32(__M & 0xFF01))\ + break;\ + else if(__i)\ + __M = prng_successor(__M, (__i == 7) ? 48 : 8);\ + else + +#define LF_POLY_ODD (0x29CE5C) +#define LF_POLY_EVEN (0x870804) +#define BIT(x, n) ((x) >> (n) & 1) +#define BEBIT(x, n) BIT(x, (n) ^ 24) +static inline int filter(uint32_t const x) +{ + uint32_t f; + + f = 0xf22c0 >> (x & 0xf) & 16; + f |= 0x6c9c0 >> (x >> 4 & 0xf) & 8; + f |= 0x3c8b0 >> (x >> 8 & 0xf) & 4; + f |= 0x1e458 >> (x >> 12 & 0xf) & 2; + f |= 0x0d938 >> (x >> 16 & 0xf) & 1; + return BIT(0xEC57E80A, f); +} +#ifdef __cplusplus +} +#endif +#endif diff --git a/common/crapto1/crypto1.c b/common/crapto1/crypto1.c new file mode 100644 index 000000000..4ddcb23db --- /dev/null +++ b/common/crapto1/crypto1.c @@ -0,0 +1,119 @@ +/* crypto1.c + + 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 2 + 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. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, US + + Copyright (C) 2008-2008 bla +*/ +#include "crapto1.h" + +#include +#include "parity.h" + +#define SWAPENDIAN(x)\ + (x = (x >> 8 & 0xff00ff) | (x & 0xff00ff) << 8, x = x >> 16 | x << 16) + +#if defined(__arm__) && !defined(__linux__) && !defined(_WIN32) && !defined(__APPLE__) // bare metal ARM Proxmark lacks malloc()/free() +void crypto1_create(struct Crypto1State *s, uint64_t key) +{ + int i; + + for(i = 47;s && i > 0; i -= 2) { + s->odd = s->odd << 1 | BIT(key, (i - 1) ^ 7); + s->even = s->even << 1 | BIT(key, i ^ 7); + } + return; +} +void crypto1_destroy(struct Crypto1State *state) +{ + state->odd = 0; + state->even = 0; +} +#else +struct Crypto1State * crypto1_create(uint64_t key) +{ + struct Crypto1State *s = malloc(sizeof(*s)); + if ( !s ) return NULL; + + s->odd = s->even = 0; + + int i; + //for(i = 47;s && i > 0; i -= 2) { + for(i = 47; i > 0; i -= 2) { + s->odd = s->odd << 1 | BIT(key, (i - 1) ^ 7); + s->even = s->even << 1 | BIT(key, i ^ 7); + } + return s; +} +void crypto1_destroy(struct Crypto1State *state) +{ + free(state); +} +#endif +void crypto1_get_lfsr(struct Crypto1State *state, uint64_t *lfsr) +{ + int i; + for(*lfsr = 0, i = 23; i >= 0; --i) { + *lfsr = *lfsr << 1 | BIT(state->odd, i ^ 3); + *lfsr = *lfsr << 1 | BIT(state->even, i ^ 3); + } +} +uint8_t crypto1_bit(struct Crypto1State *s, uint8_t in, int is_encrypted) +{ + uint32_t feedin, tmp; + uint8_t ret = filter(s->odd); + + feedin = ret & !!is_encrypted; + feedin ^= !!in; + feedin ^= LF_POLY_ODD & s->odd; + feedin ^= LF_POLY_EVEN & s->even; + s->even = s->even << 1 | evenparity32(feedin); + + tmp = s->odd; + s->odd = s->even; + s->even = tmp; + + return ret; +} +uint8_t crypto1_byte(struct Crypto1State *s, uint8_t in, int is_encrypted) +{ + uint8_t i, ret = 0; + + for (i = 0; i < 8; ++i) + ret |= crypto1_bit(s, BIT(in, i), is_encrypted) << i; + + return ret; +} +uint32_t crypto1_word(struct Crypto1State *s, uint32_t in, int is_encrypted) +{ + uint32_t i, ret = 0; + + for (i = 0; i < 32; ++i) + ret |= crypto1_bit(s, BEBIT(in, i), is_encrypted) << (i ^ 24); + + return ret; +} + +/* prng_successor + * helper used to obscure the keystream during authentication + */ +uint32_t prng_successor(uint32_t x, uint32_t n) +{ + SWAPENDIAN(x); + while(n--) + x = x >> 1 | (x >> 16 ^ x >> 18 ^ x >> 19 ^ x >> 21) << 31; + + return SWAPENDIAN(x); +} diff --git a/common/crapto1/readme b/common/crapto1/readme new file mode 100644 index 000000000..d57fa3e08 --- /dev/null +++ b/common/crapto1/readme @@ -0,0 +1,27 @@ +CRAPTO1 +------- + Provides a set of library functions which aid the verification + of crypto1 weaknesses. + + In short a partial implementation of: + Dismantling MIFARE Classic + URL: http://www.sos.cs.ru.nl/applications/rfid/2008-esorics.pdf + Flavio D. Garcia, Gerhard de Koning Gans, Ruben Muijrers, + Peter van Rossum, Roel Verdult, Ronny Wichers Schreur, Bart Jacobs + Institute for Computing and Information Sciences, + Radboud University Nijmegen, The Netherlands + {{flaviog,petervr,ronny,bart}@cs, {gkoningg,rmuijrer,rverdult}@sci}.ru.nl + and + Wirelessly Pickpocketing a Mifare Classic Card + URL: http://www.cs.ru.nl/~flaviog/publications/Pickpocketing.Mifare.pdf + Flavio D. Garcia, Peter van Rossum, Roel Verdult, Ronny Wichers Schreur + Radboud University Nijmegen, The Netherlands + {flaviog,petervr,rverdult,ronny}@cs.ru.nl + and + THE DARK SIDE OF SECURITY BY OBSCURITY + URL: http://eprint.iacr.org/2009/137 + and Cloning MiFare Classic Rail and Building Passes, Anywhere, Anytime + Nicolas T. Courtois + University College London, Computer Science, + Gower street, WC1E 6BT, London, UK + diff --git a/uart/README.md b/uart/README.md new file mode 100644 index 000000000..218e983cf --- /dev/null +++ b/uart/README.md @@ -0,0 +1,13 @@ +# 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/uart/uart.h b/uart/uart.h new file mode 100644 index 000000000..fe75a683f --- /dev/null +++ b/uart/uart.h @@ -0,0 +1,98 @@ +/* + * Generic uart / rs232/ serial port library + * + * Copyright (c) 2013, Roel Verdult + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * @file uart.h + */ + +#ifndef _PM3_UART_H_ +#define _PM3_UART_H_ + +#include +#include +#include + +#include +#include + +typedef unsigned char byte_t; + +/* 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); + +/* 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. + */ +bool uart_receive(const serial_port sp, byte_t* pbtRx, size_t pszMaxRxLen, size_t* pszRxLen); + +/* Sends a buffer to a given serial port. + * pbtTx: A pointer to a buffer containing the data to send. + * szTxLen: The amount of data to be sent. + */ +bool uart_send(const serial_port sp, const byte_t* pbtTx, const size_t szTxLen); + +/* 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); + +#endif // _PM3_UART_H_ + diff --git a/uart/uart_posix.c b/uart/uart_posix.c new file mode 100644 index 000000000..3db8873eb --- /dev/null +++ b/uart/uart_posix.c @@ -0,0 +1,337 @@ +/* + * Generic uart / rs232/ serial port library + * + * Copyright (c) 2013, Roel Verdult + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * @file uart_posix.c + * + * This version of the library has functionality removed which was not used by + * proxmark3 project. + */ + +#include "uart.h" + +// Test if we are dealing with posix operating systems +#ifndef _WIN32 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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; + +// Set time-out on 30 miliseconds +const struct timeval timeout = { + .tv_sec = 0, // 0 second + .tv_usec = 30000 // 30000 micro seconds +}; + +serial_port uart_open(const char* pcPortName) +{ + serial_port_unix* sp = malloc(sizeof(serial_port_unix)); + if (sp == 0) return INVALID_SERIAL_PORT; + + 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); + + // set speed, works for UBUNTU 14.04 + bool err = uart_set_speed(sp, 460800); + if (!err) + uart_set_speed(sp, 115200); + + return sp; +} + +void uart_close(const serial_port sp) { + serial_port_unix* spu = (serial_port_unix*)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) { + //perror("fcntl"); + } + close(spu->fd); + free(sp); +} + +bool uart_cts(const serial_port sp) { + char status; + if (ioctl(((serial_port_unix*)sp)->fd,TIOCMGET,&status) < 0) return false; + return (status & TIOCM_CTS); +} + +bool uart_receive(const serial_port sp, byte_t* pbtRx, size_t pszMaxRxLen, size_t* pszRxLen) { + int res; + int byteCount; + fd_set rfds; + struct timeval tv; + + // Reset the output count + *pszRxLen = 0; + + do { + // Reset file descriptor + FD_ZERO(&rfds); + FD_SET(((serial_port_unix*)sp)->fd,&rfds); + tv = timeout; + res = select(((serial_port_unix*)sp)->fd+1, &rfds, NULL, NULL, &tv); + + // Read error + if (res < 0) { + return false; + } + + // Read time-out + if (res == 0) { + if (*pszRxLen == 0) { + // Error, we received no data + return false; + } else { + // We received some data, but nothing more is available + return true; + } + } + + // Retrieve the count of the incoming bytes + res = ioctl(((serial_port_unix*)sp)->fd, FIONREAD, &byteCount); + if (res < 0) return false; + + // Cap the number of bytes, so we don't overrun the buffer + if (pszMaxRxLen - (*pszRxLen) < byteCount) { + byteCount = pszMaxRxLen - (*pszRxLen); + } + + // There is something available, read the data + res = read(((serial_port_unix*)sp)->fd, pbtRx+(*pszRxLen), byteCount); + + // Stop if the OS has some troubles reading the data + if (res <= 0) return false; + + *pszRxLen += res; + + if (*pszRxLen == pszMaxRxLen) { + // We have all the data we wanted. + return true; + } + + } while (byteCount); + + return true; +} + +bool uart_send(const serial_port sp, const byte_t* pbtTx, const size_t szTxLen) { + int32_t res; + size_t szPos = 0; + fd_set rfds; + struct timeval tv; + + while (szPos < szTxLen) { + // Reset file descriptor + FD_ZERO(&rfds); + FD_SET(((serial_port_unix*)sp)->fd,&rfds); + tv = timeout; + res = select(((serial_port_unix*)sp)->fd+1, NULL, &rfds, NULL, &tv); + + // Write error + if (res < 0) { + printf("write error\n"); + return false; + } + + // Write time-out + if (res == 0) { + printf("write time-out\n"); + return false; + } + + // Send away the bytes + res = write(((serial_port_unix*)sp)->fd,pbtTx+szPos,szTxLen-szPos); + + // Stop if the OS has some troubles sending the data + if (res <= 0) { + printf("os troubles\n"); + return false; + } + + szPos += res; + } + return true; +} + +bool uart_set_speed(serial_port sp, const uint32_t uiPortSpeed) { + const serial_port_unix* spu = (serial_port_unix*)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 + 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); + return (tcsetattr(spu->fd,TCSANOW,&ti) != -1); +} + +uint32_t uart_get_speed(const serial_port sp) { + struct termios ti; + uint32_t uiPortSpeed; + const serial_port_unix* spu = (serial_port_unix*)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/uart/uart_win32.c b/uart/uart_win32.c new file mode 100644 index 000000000..9213753d5 --- /dev/null +++ b/uart/uart_win32.c @@ -0,0 +1,140 @@ +/* + * Generic uart / rs232/ serial port library + * + * Copyright (c) 2013, Roel Verdult + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * @file uart_win32.c + * + * Note: the win32 version of this library has also been seen under the GPLv3+ + * license as part of the libnfc project, which appears to have additional + * contributors. + * + * This version of the library has functionality removed which was not used by + * proxmark3 project. + */ + +#include "uart.h" + +// The windows serial port implementation +#ifdef _WIN32 +#include + +typedef struct { + HANDLE hPort; // Serial port handle + DCB dcb; // Device control settings + COMMTIMEOUTS ct; // Serial port time-out configuration +} serial_port_windows; + +void upcase(char *p) { + while(*p != '\0') { + if(*p >= 97 && *p <= 122) { + *p -= 32; + } + ++p; + } +} + +serial_port uart_open(const char* pcPortName) { + char acPortName[255]; + serial_port_windows* sp = malloc(sizeof(serial_port_windows)); + + // Copy the input "com?" to "\\.\COM?" format + sprintf(acPortName,"\\\\.\\%s",pcPortName); + upcase(acPortName); + + // Try to open the serial port + 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 + 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); + return INVALID_SERIAL_PORT; + } + + // Update the active serial port + if(!SetCommState(sp->hPort,&sp->dcb)) { + uart_close(sp); + return INVALID_SERIAL_PORT; + } + // all zero's configure: no timeout for read/write used. + sp->ct.ReadIntervalTimeout = 0;//1; + sp->ct.ReadTotalTimeoutMultiplier = 0;//1; + sp->ct.ReadTotalTimeoutConstant = 30; + sp->ct.WriteTotalTimeoutMultiplier = 0;//1; + sp->ct.WriteTotalTimeoutConstant = 30; + + if(!SetCommTimeouts(sp->hPort,&sp->ct)) { + uart_close(sp); + return INVALID_SERIAL_PORT; + } + + PurgeComm(sp->hPort, PURGE_RXABORT | PURGE_RXCLEAR); + + bool err = uart_set_speed(sp, 460800); + if (!err) + uart_set_speed(sp, 115200); + + return sp; +} + +void uart_close(const serial_port sp) { + CloseHandle(((serial_port_windows*)sp)->hPort); + free(sp); +} + +bool uart_receive(const serial_port sp, byte_t* pbtRx, size_t pszMaxRxLen, size_t* pszRxLen) { + ReadFile(((serial_port_windows*)sp)->hPort,pbtRx,pszMaxRxLen,(LPDWORD)pszRxLen,NULL); + return (*pszRxLen != 0); +} + +bool uart_send(const serial_port sp, const byte_t* pbtTx, const size_t szTxLen) { + DWORD dwTxLen = 0; + return WriteFile(((serial_port_windows*)sp)->hPort,pbtTx,szTxLen,&dwTxLen,NULL); + return (dwTxLen != 0); +} + +bool uart_set_speed(serial_port sp, const uint32_t uiPortSpeed) { + serial_port_windows* spw; + spw = (serial_port_windows*)sp; + spw->dcb.BaudRate = uiPortSpeed; + return SetCommState(spw->hPort, &spw->dcb); +} + +uint32_t uart_get_speed(const serial_port sp) { + const serial_port_windows* spw = (serial_port_windows*)sp; + if (!GetCommState(spw->hPort, (serial_port)&spw->dcb)) { + return spw->dcb.BaudRate; + } + return 0; +} + +#endif