X-Git-Url: http://cvs.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/b359cee677eb741b0fe6fe14a031da2b6f6cdfac..4c685ac887bb6b83473330e31888b2165243f881:/client/nonce2key/crapto1.c

diff --git a/client/nonce2key/crapto1.c b/client/nonce2key/crapto1.c
index ca926a73..6d2ae9af 100644
--- a/client/nonce2key/crapto1.c
+++ b/client/nonce2key/crapto1.c
@@ -21,14 +21,20 @@
 #include <stdlib.h>
 
 #if !defined LOWMEM && defined __GNUC__
-static uint8_t filterlut[1 << 20];
+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);
+	uint32_t x;
+	uint32_t f;
+	for(x = 0; x < 1 << 20; ++x) {
+		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;
+		filterlut[x] = BIT(0xEC57E80A, f);
+	}
 }
-#define filter(x) (filterlut[(x) & 0xfffff])
 #endif
 
 
@@ -46,7 +52,7 @@ typedef struct bucket_info {
 		} 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,
@@ -55,28 +61,28 @@ static void bucket_sort_intersect(uint32_t* const estart, uint32_t* const estop,
 	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 (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;
@@ -147,9 +153,9 @@ extend_table(uint32_t *tbl, uint32_t **end, int bit, int m1, int m2, uint32_t in
 			*p ^= in;
 		} else {										// drop
 			*p-- = *(*end)--;
-		} 
 	}
-	
+	}
+
 }
 
 
@@ -159,7 +165,7 @@ extend_table(uint32_t *tbl, uint32_t **end, int bit, int m1, int m2, uint32_t in
 static inline void
 extend_table_simple(uint32_t *tbl, uint32_t **end, int bit)
 {
-	for(*tbl <<= 1; tbl <= *end; *++tbl <<= 1)	
+	for(*tbl <<= 1; tbl <= *end; *++tbl <<= 1)
 		if(filter(*tbl) ^ filter(*tbl | 1)) {	// replace
 			*tbl |= filter(*tbl) ^ bit;
 		} else if(filter(*tbl) == bit) {		// insert
@@ -206,13 +212,13 @@ recover(uint32_t *o_head, uint32_t *o_tail, uint32_t oks,
 	}
 
 	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
@@ -251,7 +257,6 @@ struct Crypto1State* lfsr_recovery32(uint32_t ks2, uint32_t in)
 			}
 		}
 
-	
 	// 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))
@@ -272,9 +277,7 @@ struct Crypto1State* lfsr_recovery32(uint32_t ks2, uint32_t in)
 
 	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);
-
+	recover(odd_head, odd_tail, oks, even_head, even_tail, eks, 11, statelist, in << 1, bucket);
 
 out:
 	free(odd_head);
@@ -282,7 +285,7 @@ out:
 	for (uint32_t i = 0; i < 2; i++)
 		for (uint32_t j = 0; j <= 0xff; j++)
 			free(bucket[i][j].head);
-	
+
 	return statelist;
 }
 
@@ -382,9 +385,12 @@ struct Crypto1State* lfsr_recovery64(uint32_t ks2, uint32_t ks3)
 void lfsr_rollback_bit(struct Crypto1State *s, uint32_t in, int fb)
 {
 	int out;
+	uint32_t tmp;
 
 	s->odd &= 0xffffff;
-	s->odd ^= (s->odd ^= s->even, s->even ^= s->odd);
+	tmp = s->odd;
+	s->odd = s->even;
+	s->even = tmp;
 
 	out = s->even & 1;
 	out ^= LF_POLY_EVEN & (s->even >>= 1);
@@ -489,20 +495,20 @@ brute_top(uint32_t prefix, uint32_t rresp, unsigned char parities[8][8],
 	for(c = 0; c < 8; ++c) {
 		s.odd = odd ^ fastfwd[1][c];
 		s.even = even ^ fastfwd[0][c];
-		
+
 		lfsr_rollback_bit(&s, 0, 0);
 		lfsr_rollback_bit(&s, 0, 0);
 		lfsr_rollback_bit(&s, 0, 0);
-		
+
 		lfsr_rollback_word(&s, 0, 0);
 		lfsr_rollback_word(&s, prefix | c << 5, 1);
-		
+
 		sl->odd = s.odd;
 		sl->even = s.even;
-		
+
 		if (no_chk)
 			break;
-	
+
 		ks1 = crypto1_word(&s, prefix | c << 5, 1);
 		ks2 = crypto1_word(&s,0,0);
 		ks3 = crypto1_word(&s, 0,0);
@@ -521,7 +527,7 @@ brute_top(uint32_t prefix, uint32_t rresp, unsigned char parities[8][8],
 	}
 
 	return ++sl;
-} 
+}
 
 
 /** lfsr_common_prefix
@@ -533,8 +539,7 @@ brute_top(uint32_t prefix, uint32_t rresp, unsigned char parities[8][8],
  * 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], uint8_t no_par)
+struct Crypto1State* lfsr_common_prefix(uint32_t pfx, uint32_t rr, uint8_t ks[8], uint8_t par[8][8], uint8_t no_par)
 {
 	struct Crypto1State *statelist, *s;
 	uint32_t *odd, *even, *o, *e, top;
@@ -542,13 +547,13 @@ lfsr_common_prefix(uint32_t pfx, uint32_t rr, uint8_t ks[8], uint8_t par[8][8],
 	odd = lfsr_prefix_ks(ks, 1);
 	even = lfsr_prefix_ks(ks, 0);
 
-	statelist = malloc((sizeof *statelist) << 21);	//how large should be? 
+	statelist = malloc((sizeof *statelist) << 21);	//how large should be?
 	if(!statelist || !odd || !even)
 	{
-				free(statelist);
-				free(odd);
-				free(even);
-	   return 0;
+		free(statelist);
+		free(odd);
+		free(even);
+		return 0;
 	}
 
 	s = statelist;
@@ -560,7 +565,7 @@ lfsr_common_prefix(uint32_t pfx, uint32_t rr, uint8_t ks[8], uint8_t par[8][8],
 				s = brute_top(pfx, rr, par, *o, *e, s, no_par);
 			}
 
-	s->odd = s->even = -1;	
+	s->odd = s->even = -1;
 	//printf("state count = %d\n",s-statelist);
 
 	free(odd);
@@ -568,3 +573,66 @@ lfsr_common_prefix(uint32_t pfx, uint32_t rr, uint8_t ks[8], uint8_t par[8][8],
 
 	return statelist;
 }
+
+/*
+struct Crypto1State* lfsr_common_prefix(uint32_t pfx, uint32_t rr, uint8_t ks[8], uint8_t par[8][8], uint8_t no_par, uint32_t nt, uint32_t uid)
+{
+    long long int amount = 0;
+    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) << 20);
+    if(!s || !odd || !even) {
+		free(odd);
+		free(even);
+		free(statelist);
+		return 0;
+    }
+
+    char filename[50] = "archivo.txt";
+    sprintf(filename, "logs/%x.txt", nt);
+    PrintAndLog("Name: %s\n", filename);
+    FILE *file = fopen(filename,"w+");
+	if ( !file ) {
+		s->odd = s->even = 0;
+		free(odd);
+		free(even);
+		PrintAndLog("Failed to create file");
+		return 0;
+	}
+    PrintAndLog("Creating file... ");
+	uint32_t xored = uid^nt;
+	
+    int lastOdd = 0;
+    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;
+
+                //added by MG
+                if(lastOdd != statelist->odd){
+					// Here I create a temporal crypto1 state, 
+					// where I load the odd and even state and work with it,
+					// in order not to interfere with regular mechanism, This is what I save to file
+					struct Crypto1State *state;
+                    lastOdd = state->odd = statelist->odd; state->even = statelist->even;
+                    lfsr_rollback_word(state,xored,0);
+                    fprintf(file,"%x %x \n",state->odd,state->even);
+                    amount++;
+                }
+                //s = check_pfx_parity(pfx, rr, par, *o, *e, s); //This is not useful at all when attacking chineese cards
+				s = brute_top(pfx, rr, par, *o, *e, s, no_par); 
+            }
+
+	PrintAndLog("File created, amount %u\n",amount);
+	fclose(file);
+	s->odd = s->even = 0;
+	free(odd);
+	free(even);
+    return statelist;
+}
+ */