X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/6c84c900179a0ff0959046ff0d65c68ab9077c50..cc70889743ed9b2820713e2a912ec030f2a496bb:/client/mifarehost.c

diff --git a/client/mifarehost.c b/client/mifarehost.c
index 1939b92b..35054d25 100644
--- a/client/mifarehost.c
+++ b/client/mifarehost.c
@@ -8,17 +8,10 @@
 // mifare commands
 //-----------------------------------------------------------------------------
 
-#include <stdio.h>
-#include <stdlib.h> 
-#include <string.h>
-#include <pthread.h>
 #include "mifarehost.h"
-#include "proxmark3.h"
-//#include "radixsort.h"
-#include <time.h>
 
 // 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)
 {
@@ -229,6 +203,53 @@ 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};
+
+	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
 
@@ -633,12 +654,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;
 }