X-Git-Url: http://cvs.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/e98572a1e2dde603f31cc06f330c6abd295139de..1156e3e32f4d516933d7f3e2e730d46bcd0746fd:/client/nonce2key/nonce2key.c?ds=sidebyside

diff --git a/client/nonce2key/nonce2key.c b/client/nonce2key/nonce2key.c
index b7ab7c32..2d0590df 100644
--- a/client/nonce2key/nonce2key.c
+++ b/client/nonce2key/nonce2key.c
@@ -9,147 +9,51 @@
 //-----------------------------------------------------------------------------
 // MIFARE Darkside hack
 //-----------------------------------------------------------------------------
-
-#define __STDC_FORMAT_MACROS
-#include <inttypes.h>
-#define llx PRIx64
-
 #include "nonce2key.h"
 #include "mifarehost.h"
 #include "ui.h"
-
-int compar_state(const void * a, const void * b) {
-	// didn't work: (the result is truncated to 32 bits)
-	//return (*(int64_t*)b - *(int64_t*)a);
-
-	// better:
-	if (*(int64_t*)b == *(int64_t*)a) return 0;
-	else if (*(int64_t*)b > *(int64_t*)a) return 1;
-	else return -1;
-}
+#include "proxmark3.h"
 
 int nonce2key(uint32_t uid, uint32_t nt, uint32_t nr, uint64_t par_info, uint64_t ks_info, uint64_t * key) {
+
 	struct Crypto1State *state;
-	uint32_t i, pos, rr, nr_diff, key_count;//, ks1, ks2;
+	uint32_t i, pos, rr = 0, nr_diff;
 	byte_t bt, ks3x[8], par[8][8];
-	uint64_t key_recovered;
-	int64_t *state_s;
-	static uint32_t last_uid;
-	static int64_t *last_keylist;
-	rr = 0;
-  
-	if (last_uid != uid && last_keylist != NULL) {
-		free(last_keylist);
-		last_keylist = NULL;
-	}
-	last_uid = uid;
 
 	// Reset the last three significant bits of the reader nonce
 	nr &= 0xffffff1f;
   
 	PrintAndLog("\nuid(%08x) nt(%08x) par(%016"llx") ks(%016"llx") nr(%08"llx")\n\n", uid, nt, par_info, ks_info, nr);
 
-	for (pos=0; pos<8; pos++) {
+	for ( pos = 0; pos < 8; pos++ ) {
 		ks3x[7-pos] = (ks_info >> (pos*8)) & 0x0f;
 		bt = (par_info >> (pos*8)) & 0xff;
-		for (i=0; i<8; i++)	{
+
+		for ( i = 0; i < 8; i++) {
 			par[7-pos][i] = (bt >> i) & 0x01;
 		}
 	}
 
 	printf("|diff|{nr}    |ks3|ks3^5|parity         |\n");
 	printf("+----+--------+---+-----+---------------+\n");
-	for (i=0; i<8; i++)	{
+
+	for ( i = 0; i < 8; i++) {
 		nr_diff = nr | i << 5;
 		printf("| %02x |%08x|", i << 5, nr_diff);
 		printf(" %01x |  %01x  |", ks3x[i], ks3x[i]^5);
-		for (pos=0; pos<7; pos++) 
-			printf("%01x,", par[i][pos]);
+		for (pos = 0; pos < 7; pos++) printf("%01x,", par[i][pos]);
 		printf("%01x|\n", par[i][7]);
 	}
 	printf("+----+--------+---+-----+---------------+\n");
 
-	if ( par_info == 0 )
-		PrintAndLog("Parity is all zero, try special attack! Wait for few more seconds...");
-  
-	state = lfsr_common_prefix(nr, rr, ks3x, par, par_info==0);
-	state_s = (int64_t*)state;
-	
-	//char filename[50] ;
-    //sprintf(filename, "nt_%08x_%d.txt", nt, nr);
-    //printf("name %s\n", filename);
-	//FILE* fp = fopen(filename,"w");
-	for (i = 0; (state) && ((state + i)->odd != -1); i++)
-	{
-		lfsr_rollback_word(state+i, uid^nt, 0);
-		crypto1_get_lfsr(state + i, &key_recovered);
-		*(state_s + i) = key_recovered;
-		//fprintf(fp, "%012llx\n",key_recovered);
-	}
-	//fclose(fp);
-	
-	if(!state)
-		return 1;
-	
-	qsort(state_s, i, sizeof(*state_s), compar_state);
-	*(state_s + i) = -1;
-	
-	//Create the intersection:
-	if (par_info == 0 ) {
-		if ( last_keylist != NULL) 	{
-			int64_t *p1, *p2, *p3;
-			p1 = p3 = last_keylist; 
-			p2 = state_s;
-			while ( *p1 != -1 && *p2 != -1 ) {
-				if (compar_state(p1, p2) == 0) {
-					printf("p1:%"llx" p2:%"llx" p3:%"llx" key:%012"llx"\n",
-						(uint64_t)(p1-last_keylist),
-						(uint64_t)(p2-state_s),
-						(uint64_t)(p3-last_keylist),
-						*p1);
-					*p3++ = *p1++;
-					p2++;
-				} else {
-					while (compar_state(p1, p2) == -1) ++p1;
-					while (compar_state(p1, p2) == 1) ++p2;
-				}
-			}
-			key_count = p3 - last_keylist;
-		} else {
-			key_count = 0;
-		}
-	} else {
-		last_keylist = state_s;
-		key_count = i;
-	}
-	
-	printf("key candidates count: %d\n", key_count);
-
-	// The list may still contain several key candidates. Test each of them with mfCheckKeys
-	int res;
-	uint8_t keyBlock[6];
-	uint64_t key64;
-	for (i = 0; i < key_count; i++) {
-
-		key64 = *(last_keylist + i);
-		num_to_bytes(key64, 6, keyBlock);
-		key64 = 0;
-		res = mfCheckKeys(0, 0, false, 1, keyBlock, &key64);
-		if (!res) {
-			*key = key64;
-			free(last_keylist);
-			last_keylist = NULL;
-			if (par_info == 0)
-				free(state);
-			return 0;
-		}
-	}	
-	
-	free(last_keylist);
-	last_keylist = state_s;
-	return 1;
+	state = lfsr_common_prefix(nr, rr, ks3x, par);
+	lfsr_rollback_word(state, uid^nt, 0);
+	crypto1_get_lfsr(state, key);
+	crypto1_destroy(state);
+	return 0;
 }
 
+// *outputkey is not used...
 int tryMfk32(uint64_t myuid, uint8_t *data, uint8_t *outputkey ){
 
 	struct Crypto1State *s,*t;
@@ -188,24 +92,26 @@ int tryMfk32(uint64_t myuid, uint8_t *data, uint8_t *outputkey ){
 		crypto1_word(t, uid ^ nt, 0);
 		crypto1_word(t, nr1_enc, 1);
 		if (ar1_enc == (crypto1_word(t, 0, 0) ^ prng_successor(nt, 64))) {
-			PrintAndLog("Found Key: [%012"llx"]",key);
+			PrintAndLog("Found Key: [%012"llx"]", key);
 			isSuccess = TRUE;
 			++counter;
 			if (counter==20)
 				break;
 		}
 	}
-	free(s);
+	
+	num_to_bytes(key, 6, outputkey);
+	crypto1_destroy(t);
 	return isSuccess;
 }
 
 int tryMfk32_moebius(uint64_t myuid, uint8_t *data, uint8_t *outputkey ){
 
-	struct Crypto1State *s,*t;
+	struct Crypto1State *s, *t;
 	uint64_t key;     // recovered key
 	uint32_t uid;     // serial number
-	uint32_t nt0;      // tag challenge first
-	uint32_t nt1;      // tag challenge second
+	uint32_t nt0;     // tag challenge first
+	uint32_t nt1;     // tag challenge second
 	uint32_t nr0_enc; // first encrypted reader challenge
 	uint32_t ar0_enc; // first encrypted reader response
 	uint32_t nr1_enc; // second encrypted reader challenge
@@ -239,7 +145,8 @@ int tryMfk32_moebius(uint64_t myuid, uint8_t *data, uint8_t *outputkey ){
 				break;
 		}
 	}
-	free(s);
+	num_to_bytes(key, 6, outputkey);
+	crypto1_destroy(t);
 	return isSuccess;
 }
 
@@ -285,7 +192,7 @@ int tryMfk64(uint64_t myuid, uint8_t *data, uint8_t *outputkey ){
 	lfsr_rollback_word(revstate, uid ^ nt, 0);
 	crypto1_get_lfsr(revstate, &key);
 	PrintAndLog("Found Key: [%012"llx"]",key);
+	num_to_bytes(key, 6, outputkey);
 	crypto1_destroy(revstate);
-	crypto1_destroy(pcs);
 	return 0;
 }
\ No newline at end of file