X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/4d812c139be4738acfcad094ec1f16571e2a439c..07bc72b8807c69274ffacfd9d2e716bc1338c017:/client/cmdhfmfhard.c diff --git a/client/cmdhfmfhard.c b/client/cmdhfmfhard.c index ba524c5c..2e504675 100644 --- a/client/cmdhfmfhard.c +++ b/client/cmdhfmfhard.c @@ -165,14 +165,17 @@ static int add_nonce(uint32_t nonce_enc, uint8_t par_enc) } else { // add new entry at end of existing list. p2 = p2->next = malloc(sizeof(noncelistentry_t)); } - } else if ((p1->nonce_enc & 0x00ff0000) != (nonce_enc & 0x00ff0000)) { // found distinct 2nd byte. Need to insert. + if (p2 == NULL) return 0; // memory allocation failed + } + else if ((p1->nonce_enc & 0x00ff0000) != (nonce_enc & 0x00ff0000)) { // found distinct 2nd byte. Need to insert. if (p2 == NULL) { // need to insert at start of list p2 = nonces[first_byte].first = malloc(sizeof(noncelistentry_t)); } else { p2 = p2->next = malloc(sizeof(noncelistentry_t)); } - } else { // we have seen this 2nd byte before. Nothing to add or insert. - return (0); + if (p2 == NULL) return 0; // memory allocation failed + } else { + return 0; // we have seen this 2nd byte before. Nothing to add or insert. } // add or insert new data @@ -189,7 +192,7 @@ static int add_nonce(uint32_t nonce_enc, uint8_t par_enc) nonces[first_byte].Sum += evenparity32((nonce_enc & 0x00ff0000) | (par_enc & 0x04)); nonces[first_byte].updated = true; // indicates that we need to recalculate the Sum(a8) probability for this first byte - return (1); // new nonce added + return 1; // new nonce added } static void init_nonce_memory(void) @@ -720,8 +723,8 @@ static void simulate_acquire_nonces() cuid = (rand() & 0xff) << 24 | (rand() & 0xff) << 16 | (rand() & 0xff) << 8 | (rand() & 0xff); known_target_key = ((uint64_t)rand() & 0xfff) << 36 | ((uint64_t)rand() & 0xfff) << 24 | ((uint64_t)rand() & 0xfff) << 12 | ((uint64_t)rand() & 0xfff); - printf("Simulating nonce acquisition for target key %012"llx", cuid %08x ...\n", known_target_key, cuid); - fprintf(fstats, "%012"llx";%08x;", known_target_key, cuid); + printf("Simulating nonce acquisition for target key %012" PRIx64 ", cuid %08x ...\n", known_target_key, cuid); + fprintf(fstats, "%012" PRIx64 ";%08x;", known_target_key, cuid); do { uint32_t nt_enc = 0; @@ -774,20 +777,20 @@ static int acquire_nonces(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_ uint32_t next_fivehundred = 500; uint32_t total_added_nonces = 0; uint32_t idx = 1; + uint32_t timeout = 0; FILE *fnonces = NULL; field_off = false; - UsbCommand resp; UsbCommand c = {CMD_MIFARE_ACQUIRE_ENCRYPTED_NONCES, {0,0,0} }; memcpy(c.d.asBytes, key, 6); c.arg[0] = blockNo + (keyType * 0x100); c.arg[1] = trgBlockNo + (trgKeyType * 0x100); - + printf("Acquiring nonces...\n"); do { + flags = 0; - //flags |= initialize ? 0x0001 : 0; - flags |= 0x0001; + flags |= initialize ? 0x0001 : 0; flags |= slow ? 0x0002 : 0; flags |= field_off ? 0x0004 : 0; c.arg[2] = flags; @@ -797,10 +800,15 @@ static int acquire_nonces(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_ if (field_off) break; - if (!WaitForResponseTimeout(CMD_ACK, &resp, 3000)) { - if (fnonces) fclose(fnonces); - return 1; - } + while(!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { + timeout++; + printf("."); + if (timeout > 3) { + PrintAndLog("\nNo response from Proxmark. Aborting..."); + if (fnonces) fclose(fnonces); + return 1; + } + } if (resp.arg[0]) { if (fnonces) fclose(fnonces); @@ -862,22 +870,17 @@ static int acquire_nonces(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_ total_added_nonces, NONCES_THRESHOLD * idx, CONFIDENCE_THRESHOLD * 100.0, - num_good_first_bytes); + num_good_first_bytes + ); } - if ( num_good_first_bytes > 0 ) { - //printf("GOOD BYTES: %s \n", sprint_hex(best_first_bytes, num_good_first_bytes) ); - if ( total_added_nonces >= (NONCES_THRESHOLD * idx)) { - - CmdFPGAOff(""); - - bool cracking = generate_candidates(first_byte_Sum, nonces[best_first_bytes[0]].Sum8_guess); - if (cracking || known_target_key != -1) { - field_off = brute_force(); // switch off field with next SendCommand and then finish - if (field_off) break; + if (total_added_nonces >= (NONCES_THRESHOLD * idx)) { + if (num_good_first_bytes > 0) { + if (generate_candidates(first_byte_Sum, nonces[best_first_bytes[0]].Sum8_guess) || known_target_key != -1) { + field_off = brute_force(); // switch off field with next SendCommand and then finish } - idx++; } + idx++; } } } while (!finished); @@ -1244,8 +1247,8 @@ static bool TestIfKeyExists(uint64_t key) uint32_t state_odd = pcs->odd & 0x00ffffff; uint32_t state_even = pcs->even & 0x00ffffff; - //printf("Tests: searching for key %llx after first byte 0x%02x (state_odd = 0x%06x, state_even = 0x%06x) ...\n", key, best_first_bytes[0], state_odd, state_even); - printf("Validating keysearch space\n"); + //printf("Tests: searching for key %" PRIx64 " after first byte 0x%02x (state_odd = 0x%06x, state_even = 0x%06x) ...\n", key, best_first_bytes[0], state_odd, state_even); + printf("Validating key search space\n"); uint64_t count = 0; for (statelist_t *p = candidates; p != NULL; p = p->next) { bool found_odd = false; @@ -1260,23 +1263,22 @@ static bool TestIfKeyExists(uint64_t key) p_odd++; } while (*p_even != END_OF_LIST_MARKER) { - if ((*p_even & 0x00ffffff) == state_even) { + if ((*p_even & 0x00ffffff) == state_even) found_even = true; - } + p_even++; } count += (p_odd - p->states[ODD_STATE]) * (p_even - p->states[EVEN_STATE]); if (found_odd && found_even) { if (known_target_key != -1) { - PrintAndLog("Key Found after testing %llu (2^%1.1f) out of %lld (2^%1.1f) keys.", - count, - log(count)/log(2), - maximum_states, - log(maximum_states)/log(2) - ); - if (write_stats) { - fprintf(fstats, "1\n"); - } + PrintAndLog("Key Found after testing %" PRIu64 " (2^%1.1f) out of %lld (2^%1.1f) keys.", + count, + log(count)/log(2), + maximum_states, + log(maximum_states)/log(2) + ); + if (write_stats) + fprintf(fstats, "1\n"); } crypto1_destroy(pcs); return true; @@ -1284,13 +1286,11 @@ static bool TestIfKeyExists(uint64_t key) } if (known_target_key != -1) { - printf("Key NOT found!\n"); - if (write_stats) { - fprintf(fstats, "0\n"); - } + printf("Key NOT found!\n"); + if (write_stats) + fprintf(fstats, "0\n"); } crypto1_destroy(pcs); - return false; } @@ -1375,7 +1375,7 @@ static bool generate_candidates(uint16_t sum_a0, uint16_t sum_a8) return false; } -static void free_candidates_memory(statelist_t *sl) +static void free_candidates_memory(statelist_t *sl) { if (sl == NULL) { return; @@ -1634,19 +1634,23 @@ static void* crack_states_thread(void* x){ const uint64_t key = crack_states_bitsliced(bucket); if (keys_found) break; - else if(key != -1 && TestIfKeyExists(key)) { + else if(key != -1) { + if (TestIfKeyExists(key)) { __sync_fetch_and_add(&keys_found, 1); __sync_fetch_and_add(&foundkey, key); + printf("*"); + fflush(stdout); break; + } + printf("!"); + fflush(stdout); } else { printf("."); fflush(stdout); } } - current_bucket += thread_count; } - return NULL; } @@ -1725,12 +1729,14 @@ static bool brute_force(void) { return ret; } -int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t *trgkey, bool nonce_file_read, bool nonce_file_write, bool slow, int tests) +int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t *trgkey, bool nonce_file_read, bool nonce_file_write, bool slow, int tests, uint64_t *found_key) { // initialize Random number generator time_t t; srand((unsigned) time(&t)); + *found_key = 0; + if (trgkey != NULL) { known_target_key = bytes_to_num(trgkey, 6); } else { @@ -1782,6 +1788,10 @@ int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBloc } else { // acquire nonces. uint16_t is_OK = acquire_nonces(blockNo, keyType, key, trgBlockNo, trgKeyType, nonce_file_write, slow); if (is_OK != 0) { + free_nonces_memory(); + //free_statelist_cache(); + free_candidates_memory(candidates); + candidates = NULL; return is_OK; } } @@ -1792,5 +1802,6 @@ int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBloc free_candidates_memory(candidates); candidates = NULL; } + *found_key = foundkey; return 0; -} +} \ No newline at end of file