X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/6c84c900179a0ff0959046ff0d65c68ab9077c50..36dc0b437017bf360787afe3c15fd3cbaf941dd2:/client/mifarehost.c diff --git a/client/mifarehost.c b/client/mifarehost.c index 1939b92b..f9e05807 100644 --- a/client/mifarehost.c +++ b/client/mifarehost.c @@ -8,17 +8,10 @@ // mifare commands //----------------------------------------------------------------------------- -#include -#include -#include -#include #include "mifarehost.h" -#include "proxmark3.h" -//#include "radixsort.h" -#include // MIFARE -int compar_int(const void * a, const void * b) { +extern int compar_int(const void * a, const void * b) { // didn't work: (the result is truncated to 32 bits) //return (*(uint64_t*)b - *(uint64_t*)a); @@ -44,25 +37,6 @@ int Compare16Bits(const void * a, const void * b) { */ } -typedef - struct { - union { - struct Crypto1State *slhead; - uint64_t *keyhead; - } head; - union { - struct Crypto1State *sltail; - uint64_t *keytail; - } tail; - uint32_t len; - uint32_t uid; - uint32_t blockNo; - uint32_t keyType; - uint32_t nt; - uint32_t ks1; - } StateList_t; - - // wrapper function for multi-threaded lfsr_recovery32 void* nested_worker_thread(void *arg) { @@ -151,8 +125,8 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t * key, uint8_t trgBlockNo p4->even = 0; p4->odd = 0; statelists[0].len = p3 - statelists[0].head.slhead; statelists[1].len = p4 - statelists[1].head.slhead; - statelists[0].tail.sltail=--p3; - statelists[1].tail.sltail=--p4; + statelists[0].tail.sltail = --p3; + statelists[1].tail.sltail = --p4; // the statelists now contain possible keys. The key we are searching for must be in the // intersection of both lists. Create the intersection: @@ -229,15 +203,60 @@ int mfCheckKeys (uint8_t blockNo, uint8_t keyType, bool clear_trace, uint8_t key *key = bytes_to_num(resp.d.asBytes, 6); return 0; } +// PM3 imp of J-Run mf_key_brute (part 2) +// ref: https://github.com/J-Run/mf_key_brute +int mfKeyBrute(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint64_t *resultkey){ + + #define KEYS_IN_BLOCK 85 + #define KEYBLOCK_SIZE 510 + #define CANDIDATE_SIZE 0xFFFF * 6 + uint8_t found = FALSE; + uint64_t key64 = 0; + uint8_t candidates[CANDIDATE_SIZE] = {0x00}; + uint8_t keyBlock[KEYBLOCK_SIZE] = {0x00}; -// EMULATOR + memset(candidates, 0, sizeof(candidates)); + memset(keyBlock, 0, sizeof(keyBlock)); + + // Generate all possible keys for the first two unknown bytes. + for (uint16_t i = 0; i < 0xFFFF; ++i) { + uint32_t j = i * 6; + candidates[0 + j] = i >> 8; + candidates[1 + j] = i; + candidates[2 + j] = key[2]; + candidates[3 + j] = key[3]; + candidates[4 + j] = key[4]; + candidates[5 + j] = key[5]; + } + uint32_t counter, i; + for ( i = 0, counter = 1; i < CANDIDATE_SIZE; i += KEYBLOCK_SIZE, ++counter){ + key64 = 0; + + // copy candidatekeys to test key block + memcpy(keyBlock, candidates + i, KEYBLOCK_SIZE); + + // check a block of generated candidate keys. + if (!mfCheckKeys(blockNo, keyType, TRUE, KEYS_IN_BLOCK, keyBlock, &key64)) { + *resultkey = key64; + found = TRUE; + break; + } + + // progress + if ( counter % 20 == 0 ) + PrintAndLog("tried : %s.. \t %u keys", sprint_hex(candidates + i, 6), counter * KEYS_IN_BLOCK ); + } + return found; +} + +// EMULATOR int mfEmlGetMem(uint8_t *data, int blockNum, int blocksCount) { UsbCommand c = {CMD_MIFARE_EML_MEMGET, {blockNum, blocksCount, 0}}; clearCommandBuffer(); SendCommand(&c); UsbCommand resp; - if (!WaitForResponseTimeout(CMD_ACK,&resp,1500)) return 1; + if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) return 1; memcpy(data, resp.d.asBytes, blocksCount * 16); return 0; } @@ -391,14 +410,20 @@ int loadTraceCard(uint8_t *tuid, uint8_t uidlen) { memset(buf, 0, sizeof(buf)); if (fgets(buf, sizeof(buf), f) == NULL) { PrintAndLog("No trace file found or reading error."); - fclose(f); + if (f) { + fclose(f); + f = NULL; + } return 2; } if (strlen(buf) < 32){ if (feof(f)) break; PrintAndLog("File content error. Block data must include 32 HEX symbols"); - fclose(f); + if (f) { + fclose(f); + f = NULL; + } return 2; } for (i = 0; i < 32; i += 2) @@ -408,7 +433,10 @@ int loadTraceCard(uint8_t *tuid, uint8_t uidlen) { blockNum++; } - fclose(f); + if (f) { + fclose(f); + f = NULL; + } return 0; } @@ -426,7 +454,10 @@ int saveTraceCard(void) { fprintf(f,"\n"); } fflush(f); - fclose(f); + if (f) { + fclose(f); + f = NULL; + } return 0; } @@ -633,12 +664,12 @@ int mfTraceDecode(uint8_t *data_src, int len, bool wantSaveToEmlFile) { int tryDecryptWord(uint32_t nt, uint32_t ar_enc, uint32_t at_enc, uint8_t *data, int len){ PrintAndLog("\nEncrypted data: [%s]", sprint_hex(data, len) ); - struct Crypto1State *pcs = NULL; + struct Crypto1State *s; ks2 = ar_enc ^ prng_successor(nt, 64); ks3 = at_enc ^ prng_successor(nt, 96); - pcs = lfsr_recovery64(ks2, ks3); - mf_crypto1_decrypt(pcs, data, len, FALSE); + s = lfsr_recovery64(ks2, ks3); + mf_crypto1_decrypt(s, data, len, FALSE); PrintAndLog("Decrypted data: [%s]", sprint_hex(data, len) ); - crypto1_destroy(pcs); + crypto1_destroy(s); return 0; }