X-Git-Url: http://cvs.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/ed7bd3a3802f6398e5a8ae38cb67516efde0e327..f9b5377fd07685592758eb54369a779bef7dae66:/armsrc/hitag2.c

diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c
index 90a95b5a..4596d3f1 100644
--- a/armsrc/hitag2.c
+++ b/armsrc/hitag2.c
@@ -21,11 +21,13 @@
 #include "util.h"
 #include "hitag2.h"
 #include "string.h"
+#include "BigBuf.h"
 
 static bool bQuiet;
-
-bool bCrypto;
-bool bPwd;
+static bool bCrypto;
+static bool bAuthenticating;
+static bool bPwd;
+static bool bSuccessful;
 
 struct hitag2_tag {
 	uint32_t uid;
@@ -41,8 +43,7 @@ struct hitag2_tag {
 	byte_t sectors[12][4];
 };
 
-static struct hitag2_tag tag;
-static const struct hitag2_tag resetdata = {
+static struct hitag2_tag tag = {
     .state = TAG_STATE_RESET,
     .sectors = {                         // Password mode:               | Crypto mode:
         [0]  = { 0x02, 0x4e, 0x02, 0x20}, // UID                          | UID
@@ -60,19 +61,17 @@ static const struct hitag2_tag resetdata = {
     },
 };
 
-//#define TRACE_LENGTH 3000
-//uint8_t *trace = (uint8_t *) BigBuf;
-//int traceLen = 0;
-//int rsamples = 0;
-
-#define AUTH_TABLE_OFFSET FREE_BUFFER_OFFSET
-#define AUTH_TABLE_LENGTH FREE_BUFFER_SIZE
-byte_t* auth_table = (byte_t *)BigBuf+AUTH_TABLE_OFFSET;
-size_t auth_table_pos = 0;
-size_t auth_table_len = AUTH_TABLE_LENGTH;
+// ToDo: define a meaningful maximum size for auth_table. The bigger this is, the lower will be the available memory for traces. 
+// Historically it used to be FREE_BUFFER_SIZE, which was 2744.
+#define AUTH_TABLE_LENGTH 2744
+static byte_t* auth_table;
+static size_t auth_table_pos = 0;
+static size_t auth_table_len = AUTH_TABLE_LENGTH;
 
-byte_t password[4];
-byte_t NrAr[8];
+static byte_t password[4];
+static byte_t NrAr[8];
+static byte_t key[8];
+static uint64_t cipher_state;
 
 /* Following is a modified version of cryptolib.com/ciphers/hitag2/ */
 // Software optimized 48-bit Philips/NXP Mifare Hitag2 PCF7936/46/47/52 stream cipher algorithm by I.C. Wiener 2006-2007.
@@ -95,7 +94,6 @@ byte_t NrAr[8];
 #define rotl64(x, n)	((((u64)(x))<<((n)&63))+(((u64)(x))>>((0-(n))&63)))
 
 // Single bit Hitag2 functions:
-
 #define i4(x,a,b,c,d)	((u32)((((x)>>(a))&1)+(((x)>>(b))&1)*2+(((x)>>(c))&1)*4+(((x)>>(d))&1)*8))
 
 static const u32 ht2_f4a = 0x2C79;		// 0010 1100 0111 1001
@@ -104,7 +102,7 @@ static const u32 ht2_f5c = 0x7907287B;	// 0111 1001 0000 0111 0010 1000 0111 101
 
 static u32 _f20 (const u64 x)
 {
-	u32					i5;
+	u32	i5;
 
 	i5 = ((ht2_f4a >> i4 (x, 1, 2, 4, 5)) & 1)* 1
 	   + ((ht2_f4b >> i4 (x, 7,11,13,14)) & 1)* 2
@@ -117,8 +115,8 @@ static u32 _f20 (const u64 x)
 
 static u64 _hitag2_init (const u64 key, const u32 serial, const u32 IV)
 {
-	u32					i;
-	u64					x = ((key & 0xFFFF) << 32) + serial;
+	u32	i;
+	u64	x = ((key & 0xFFFF) << 32) + serial;
 
 	for (i = 0; i < 32; i++)
 	{
@@ -130,7 +128,7 @@ static u64 _hitag2_init (const u64 key, const u32 serial, const u32 IV)
 
 static u64 _hitag2_round (u64 *state)
 {
-	u64					x = *state;
+	u64 x = *state;
 
 	x = (x >>  1) +
 	 ((((x >>  0) ^ (x >>  2) ^ (x >>  3) ^ (x >>  6)
@@ -142,44 +140,47 @@ static u64 _hitag2_round (u64 *state)
 	return _f20 (x);
 }
 
+// "MIKRON"             =  O  N  M  I  K  R
+// Key                  = 4F 4E 4D 49 4B 52             - Secret 48-bit key
+// Serial               = 49 43 57 69                   - Serial number of the tag, transmitted in clear
+// Random               = 65 6E 45 72                   - Random IV, transmitted in clear
+//~28~DC~80~31  = D7 23 7F CE                   - Authenticator value = inverted first 4 bytes of the keystream
+
+// The code below must print out "D7 23 7F CE 8C D0 37 A9 57 49 C1 E6 48 00 8A B6".
+// The inverse of the first 4 bytes is sent to the tag to authenticate.
+// The rest is encrypted by XORing it with the subsequent keystream.
+
 static u32 _hitag2_byte (u64 * x)
 {
-	u32					i, c;
+	u32	i, c;
 
 	for (i = 0, c = 0; i < 8; i++) c += (u32) _hitag2_round (x) << (i^7);
 	return c;
 }
 
-size_t nbytes(size_t nbits) {
-	return (nbits/8)+((nbits%8)>0);
-}
-
-int hitag2_reset(void)
-{
+static int hitag2_reset(void) {
 	tag.state = TAG_STATE_RESET;
 	tag.crypto_active = 0;
 	return 0;
 }
 
-int hitag2_init(void)
-{
-	memcpy(&tag, &resetdata, sizeof(tag));
+static int hitag2_init(void) {
 	hitag2_reset();
 	return 0;
 }
 
 static void hitag2_cipher_reset(struct hitag2_tag *tag, const byte_t *iv)
 {
-	uint64_t key = ((uint64_t)tag->sectors[2][2]) |
-			((uint64_t)tag->sectors[2][3] << 8) |
-			((uint64_t)tag->sectors[1][0] << 16) |
-			((uint64_t)tag->sectors[1][1] << 24) |
-			((uint64_t)tag->sectors[1][2] << 32) |
-			((uint64_t)tag->sectors[1][3] << 40);
-	uint32_t uid = ((uint32_t)tag->sectors[0][0]) |
-			((uint32_t)tag->sectors[0][1] << 8) |
-			((uint32_t)tag->sectors[0][2] << 16) |
-			((uint32_t)tag->sectors[0][3] << 24);
+	uint64_t key =  ((uint64_t)tag->sectors[2][2]) |
+                  ((uint64_t)tag->sectors[2][3] << 8) |
+                  ((uint64_t)tag->sectors[1][0] << 16) |
+                  ((uint64_t)tag->sectors[1][1] << 24) |
+                  ((uint64_t)tag->sectors[1][2] << 32) |
+                  ((uint64_t)tag->sectors[1][3] << 40);
+	uint32_t uid =  ((uint32_t)tag->sectors[0][0]) |
+                  ((uint32_t)tag->sectors[0][1] << 8) |
+                  ((uint32_t)tag->sectors[0][2] << 16) |
+                  ((uint32_t)tag->sectors[0][3] << 24);
 	uint32_t iv_ = (((uint32_t)(iv[0]))) |
 			(((uint32_t)(iv[1])) << 8) |
 			(((uint32_t)(iv[2])) << 16) |
@@ -225,16 +226,16 @@ static int hitag2_cipher_transcrypt(uint64_t* cs, byte_t *data, unsigned int byt
 #define HITAG_T_WAIT_2 90 /* T_wresp should be 199..206 */
 #define HITAG_T_WAIT_MAX 300 /* bit more than HITAG_T_WAIT_1 + HITAG_T_WAIT_2 */
 
-#define HITAG_T_TAG_ONE_HALF_PERIOD			10
-#define HITAG_T_TAG_TWO_HALF_PERIOD			25
-#define HITAG_T_TAG_THREE_HALF_PERIOD		41 
-#define HITAG_T_TAG_FOUR_HALF_PERIOD    57 
+#define HITAG_T_TAG_ONE_HALF_PERIOD		10
+#define HITAG_T_TAG_TWO_HALF_PERIOD		25
+#define HITAG_T_TAG_THREE_HALF_PERIOD	41 
+#define HITAG_T_TAG_FOUR_HALF_PERIOD	57 
 
-#define HITAG_T_TAG_HALF_PERIOD					16
-#define HITAG_T_TAG_FULL_PERIOD					32
+#define HITAG_T_TAG_HALF_PERIOD			16
+#define HITAG_T_TAG_FULL_PERIOD			32
 
-#define HITAG_T_TAG_CAPTURE_ONE_HALF		13
-#define HITAG_T_TAG_CAPTURE_TWO_HALF		25
+#define HITAG_T_TAG_CAPTURE_ONE_HALF	13
+#define HITAG_T_TAG_CAPTURE_TWO_HALF	25
 #define HITAG_T_TAG_CAPTURE_THREE_HALF	41 
 #define HITAG_T_TAG_CAPTURE_FOUR_HALF   57 
 
@@ -277,7 +278,8 @@ static void hitag_send_frame(const byte_t* frame, size_t frame_len)
 	LOW(GPIO_SSC_DOUT);
 }
 
-void hitag2_handle_reader_command(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen)
+
+static void hitag2_handle_reader_command(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen)
 {
 	byte_t rx_air[HITAG_FRAME_LEN];
 	
@@ -396,8 +398,8 @@ void hitag2_handle_reader_command(byte_t* rx, const size_t rxlen, byte_t* tx, si
 		break;
 	}
 
-//	LogTrace(rx,nbytes(rxlen),0,0,false);
-//	LogTrace(tx,nbytes(*txlen),0,0,true);
+//	LogTraceHitag(rx,rxlen,0,0,false);
+//	LogTraceHitag(tx,*txlen,0,0,true);
 	
 	if(tag.crypto_active) {
 		hitag2_cipher_transcrypt(&(tag.cs), tx, *txlen/8, *txlen%8);
@@ -412,7 +414,7 @@ static void hitag_reader_send_bit(int bit) {
 	// Binary puls length modulation (BPLM) is used to encode the data stream
 	// This means that a transmission of a one takes longer than that of a zero
 	
-	// Enable modulation, which means, drop the the field
+	// Enable modulation, which means, drop the field
 	HIGH(GPIO_SSC_DOUT);
 	
 	// Wait for 4-10 times the carrier period
@@ -425,15 +427,15 @@ static void hitag_reader_send_bit(int bit) {
 	if(bit == 0) {
 		// Zero bit: |_-|
 		while(AT91C_BASE_TC0->TC_CV < T0*22);
-		//		SpinDelayUs(16*8);
+
 	} else {
 		// One bit: |_--|
 		while(AT91C_BASE_TC0->TC_CV < T0*28);
-		//		SpinDelayUs(22*8);
 	}
 	LED_A_OFF();
 }
 
+
 static void hitag_reader_send_frame(const byte_t* frame, size_t frame_len)
 {
 	// Send the content of the frame
@@ -442,7 +444,7 @@ static void hitag_reader_send_frame(const byte_t* frame, size_t frame_len)
 	}
 	// Send EOF 
 	AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG;
-	// Enable modulation, which means, drop the the field
+	// Enable modulation, which means, drop the field
 	HIGH(GPIO_SSC_DOUT);
 	// Wait for 4-10 times the carrier period
 	while(AT91C_BASE_TC0->TC_CV < T0*6);
@@ -452,7 +454,7 @@ static void hitag_reader_send_frame(const byte_t* frame, size_t frame_len)
 
 size_t blocknr;
 
-bool hitag2_password(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen) {
+static bool hitag2_password(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen) {
 	// Reset the transmission frame length
 	*txlen = 0;
 	
@@ -475,29 +477,132 @@ bool hitag2_password(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen)
 				*txlen = 32;
 				memcpy(tx,password,4);
 				bPwd = true;
+				memcpy(tag.sectors[blocknr],rx,4);
+				blocknr++;
 			} else {
-        if (blocknr > 7) {
-          DbpString("Read succesful!");
-          // We are done... for now
+				
+				if(blocknr == 1){
+					//store password in block1, the TAG answers with Block3, but we need the password in memory
+					memcpy(tag.sectors[blocknr],tx,4);
+				} else {
+					memcpy(tag.sectors[blocknr],rx,4);
+				}
+				
+				blocknr++;
+				if (blocknr > 7) {
+					DbpString("Read succesful!");
+					bSuccessful = true;
+					return false;
+				}
+				*txlen = 10;
+				tx[0] = 0xc0 | (blocknr << 3) | ((blocknr^7) >> 2);
+				tx[1] = ((blocknr^7) << 6);
+			}
+		} break;
+			
+		// Unexpected response
+    default: {
+			Dbprintf("Uknown frame length: %d",rxlen);
+			return false;
+		} break;
+	}
+	return true;
+}
+
+static bool hitag2_crypto(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen) {
+	// Reset the transmission frame length
+	*txlen = 0;
+	
+  if(bCrypto) {
+		hitag2_cipher_transcrypt(&cipher_state,rx,rxlen/8,rxlen%8);
+	}
+
+	// Try to find out which command was send by selecting on length (in bits)
+	switch (rxlen) {
+      // No answer, try to resurrect
+		case 0: {
+			// Stop if there is no answer while we are in crypto mode (after sending NrAr)
+			if (bCrypto) {
+        // Failed during authentication
+        if (bAuthenticating) {
+          DbpString("Authentication failed!");
           return false;
+        } else {
+          // Failed reading a block, could be (read/write) locked, skip block and re-authenticate
+          if (blocknr == 1) {
+            // Write the low part of the key in memory
+            memcpy(tag.sectors[1],key+2,4);
+          } else if (blocknr == 2) {
+            // Write the high part of the key in memory
+            tag.sectors[2][0] = 0x00;
+            tag.sectors[2][1] = 0x00;
+            tag.sectors[2][2] = key[0];
+            tag.sectors[2][3] = key[1];
+          } else {
+            // Just put zero's in the memory (of the unreadable block)
+            memset(tag.sectors[blocknr],0x00,4);
+          }
+          blocknr++;
+          bCrypto = false;
+        }
+			} else {
+				*txlen = 5;
+				memcpy(tx,"\xc0",nbytes(*txlen));
+			}
+		} break;
+			
+      // Received UID, crypto tag answer
+		case 32: {
+			if (!bCrypto) {
+        uint64_t ui64key = key[0] | ((uint64_t)key[1]) << 8 | ((uint64_t)key[2]) << 16 | ((uint64_t)key[3]) << 24 | ((uint64_t)key[4]) << 32 | ((uint64_t)key[5]) << 40;
+        uint32_t ui32uid = rx[0] | ((uint32_t)rx[1]) << 8 | ((uint32_t)rx[2]) << 16 | ((uint32_t)rx[3]) << 24;
+        cipher_state = _hitag2_init(rev64(ui64key), rev32(ui32uid), 0);
+        memset(tx,0x00,4);
+        memset(tx+4,0xff,4);
+        hitag2_cipher_transcrypt(&cipher_state,tx+4,4,0);
+				*txlen = 64;
+				bCrypto = true;
+				bAuthenticating = true;
+			} else {
+        // Check if we received answer tag (at)
+        if (bAuthenticating) {
+			bAuthenticating = false;
+        } else {
+			// Store the received block
+			memcpy(tag.sectors[blocknr],rx,4);
+			blocknr++;
+        }
+        if (blocknr > 7) {
+			DbpString("Read succesful!");
+			bSuccessful = true;
+			return false;
         }
         *txlen = 10;
         tx[0] = 0xc0 | (blocknr << 3) | ((blocknr^7) >> 2);
         tx[1] = ((blocknr^7) << 6);
-        blocknr++;
 			}
 		} break;
 			
-		// Unexpected response
-        default: {
+      // Unexpected response
+		default: {
 			Dbprintf("Uknown frame length: %d",rxlen);
 			return false;
 		} break;
 	}
+	
+  
+	if(bCrypto) {
+		// We have to return now to avoid double encryption
+		if (!bAuthenticating) {
+		  hitag2_cipher_transcrypt(&cipher_state, tx, *txlen/8, *txlen%8);
+		}
+	}
+
 	return true;
 }
 
-bool hitag2_authenticate(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen) {
+
+static bool hitag2_authenticate(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen) {
 	// Reset the transmission frame length 
 	*txlen = 0;
 	
@@ -521,9 +626,8 @@ bool hitag2_authenticate(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txl
 				memcpy(tx,NrAr,8);
 				bCrypto = true;
 			} else {
-				DbpString("Read succesful!");
-				// We are done... for now
-				return false;
+				DbpString("Authentication succesful!");
+				return true;
 			}
 		} break;
 			
@@ -537,7 +641,9 @@ bool hitag2_authenticate(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txl
 	return true;
 }
 
-bool hitag2_test_auth_attempts(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen) {
+
+static bool hitag2_test_auth_attempts(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen) {
+
 	// Reset the transmission frame length 
 	*txlen = 0;
 	
@@ -547,12 +653,19 @@ bool hitag2_test_auth_attempts(byte_t* rx, const size_t rxlen, byte_t* tx, size_
 		case 0: {
 			// Stop if there is no answer while we are in crypto mode (after sending NrAr)
 			if (bCrypto) {
-				Dbprintf("auth: %02x%02x%02x%02x%02x%02x%02x%02x Failed!",NrAr[0],NrAr[1],NrAr[2],NrAr[3],NrAr[4],NrAr[5],NrAr[6],NrAr[7]);
+				Dbprintf("auth: %02x%02x%02x%02x%02x%02x%02x%02x Failed, removed entry!",NrAr[0],NrAr[1],NrAr[2],NrAr[3],NrAr[4],NrAr[5],NrAr[6],NrAr[7]);
+
+				// Removing failed entry from authentiations table
+				memcpy(auth_table+auth_table_pos,auth_table+auth_table_pos+8,8);
+				auth_table_len -= 8;
+
+				// Return if we reached the end of the authentications table
 				bCrypto = false;
-				if ((auth_table_pos+8) == auth_table_len) {
+				if (auth_table_pos == auth_table_len) {
 					return false;
 				}
-				auth_table_pos += 8;
+
+				// Copy the next authentication attempt in row (at the same position, b/c we removed last failed entry)
 				memcpy(NrAr,auth_table+auth_table_pos,8);
 			}
 			*txlen = 5;
@@ -585,6 +698,7 @@ bool hitag2_test_auth_attempts(byte_t* rx, const size_t rxlen, byte_t* tx, size_
 	return true;
 }
 
+
 void SnoopHitag(uint32_t type) {
 	int frame_count;
 	int response;
@@ -597,12 +711,19 @@ void SnoopHitag(uint32_t type) {
 	byte_t rx[HITAG_FRAME_LEN];
 	size_t rxlen=0;
 	
+	FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
+	
+	// free eventually allocated BigBuf memory
+	BigBuf_free(); BigBuf_Clear_ext(false);
+	
 	// Clean up trace and prepare it for storing frames
-	iso14a_set_tracing(TRUE);
-	iso14a_clear_trace();
-
+	clear_trace();
+	set_tracing(TRUE);
+	
 	auth_table_len = 0;
 	auth_table_pos = 0;
+
+    auth_table = (byte_t *)BigBuf_malloc(AUTH_TABLE_LENGTH);
 	memset(auth_table, 0x00, AUTH_TABLE_LENGTH);
 	
 	DbpString("Starting Hitag2 snoop");
@@ -610,7 +731,7 @@ void SnoopHitag(uint32_t type) {
 	
 	// Set up eavesdropping mode, frequency divisor which will drive the FPGA
 	// and analog mux selection.
-	FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT);
+	FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT  | FPGA_LF_EDGE_DETECT_TOGGLE_MODE);
 	FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
 	SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
 	RELAY_OFF();
@@ -626,7 +747,7 @@ void SnoopHitag(uint32_t type) {
 	AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC1);
 	AT91C_BASE_PIOA->PIO_BSR = GPIO_SSC_FRAME;
 	
-  // Disable timer during configuration	
+	// Disable timer during configuration	
 	AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
 	
 	// Capture mode, defaul timer source = MCK/2 (TIMER_CLOCK1), TIOA is external trigger,
@@ -647,7 +768,7 @@ void SnoopHitag(uint32_t type) {
 	bSkip = true;
 	tag_sof = 4;
 	
-	while(!BUTTON_PRESS()) {
+	while(!BUTTON_PRESS() && !usb_poll_validate_length()) {
 		// Watchdog hit
 		WDT_HIT();
 		
@@ -747,7 +868,7 @@ void SnoopHitag(uint32_t type) {
 		// Check if frame was captured
 		if(rxlen > 0) {
 			frame_count++;
-			if (!LogTrace(rx,nbytes(rxlen),response,0,reader_frame)) {
+			if (!LogTraceHitag(rx,rxlen,response,0,reader_frame)) {
 				DbpString("Trace full");
 				break;
 			}
@@ -789,7 +910,7 @@ void SnoopHitag(uint32_t type) {
     AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;
 	FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
     LED_A_OFF();
-	
+	set_tracing(TRUE);
 //	Dbprintf("frame received: %d",frame_count);
 //	Dbprintf("Authentication Attempts: %d",(auth_table_len/8));
 //	DbpString("All done");
@@ -806,11 +927,20 @@ void SimulateHitagTag(bool tag_mem_supplied, byte_t* data) {
 	bool bQuitTraceFull = false;
 	bQuiet = false;
 	
+	FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
+
+	// free eventually allocated BigBuf memory
+	BigBuf_free(); BigBuf_Clear_ext(false);
+
 	// Clean up trace and prepare it for storing frames
-    iso14a_set_tracing(TRUE);
-    iso14a_clear_trace();
+	clear_trace();
+	set_tracing(TRUE);
+	
 	auth_table_len = 0;
 	auth_table_pos = 0;
+    byte_t* auth_table;
+
+    auth_table = (byte_t *)BigBuf_malloc(AUTH_TABLE_LENGTH);
 	memset(auth_table, 0x00, AUTH_TABLE_LENGTH);
 
 	DbpString("Starting Hitag2 simulation");
@@ -833,7 +963,7 @@ void SimulateHitagTag(bool tag_mem_supplied, byte_t* data) {
 	
 	// Set up simulator mode, frequency divisor which will drive the FPGA
 	// and analog mux selection.
-	FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT);
+	FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD);
 	FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
 	SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
 	RELAY_OFF();
@@ -852,23 +982,23 @@ void SimulateHitagTag(bool tag_mem_supplied, byte_t* data) {
 	AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC1);
 	AT91C_BASE_PIOA->PIO_BSR = GPIO_SSC_FRAME;
 	
-  // Disable timer during configuration	
+    // Disable timer during configuration	
 	AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
 
-	// Capture mode, defaul timer source = MCK/2 (TIMER_CLOCK1), TIOA is external trigger,
+	// Capture mode, default timer source = MCK/2 (TIMER_CLOCK1), TIOA is external trigger,
 	// external trigger rising edge, load RA on rising edge of TIOA.
 	AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK | AT91C_TC_ETRGEDG_RISING | AT91C_TC_ABETRG | AT91C_TC_LDRA_RISING;
 	
-	// Enable and reset counter
-	AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
-
 	// Reset the received frame, frame count and timing info
 	memset(rx,0x00,sizeof(rx));
 	frame_count = 0;
 	response = 0;
 	overflow = 0;
+
+	// Enable and reset counter
+	AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
 	
-	while(!BUTTON_PRESS()) {
+	while(!BUTTON_PRESS() && !usb_poll_validate_length()) {
 		// Watchdog hit
 		WDT_HIT();
 		
@@ -910,7 +1040,7 @@ void SimulateHitagTag(bool tag_mem_supplied, byte_t* data) {
 		if(rxlen > 4) {
 			frame_count++;
 			if (!bQuiet) {
-				if (!LogTrace(rx,nbytes(rxlen),response,0,true)) {
+				if (!LogTraceHitag(rx,rxlen,response,0,true)) {
 					DbpString("Trace full");
 					if (bQuitTraceFull) {
 						break;
@@ -939,7 +1069,7 @@ void SimulateHitagTag(bool tag_mem_supplied, byte_t* data) {
 				hitag_send_frame(tx,txlen);
 				// Store the frame in the trace
 				if (!bQuiet) {
-					if (!LogTrace(tx,nbytes(txlen),0,0,false)) {
+					if (!LogTraceHitag(tx,txlen,0,0,false)) {
 						DbpString("Trace full");
 						if (bQuitTraceFull) {
 							break;
@@ -970,9 +1100,9 @@ void SimulateHitagTag(bool tag_mem_supplied, byte_t* data) {
 	AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
 	AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;
 	FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
-//	Dbprintf("frame received: %d",frame_count);
-//	Dbprintf("Authentication Attempts: %d",(auth_table_len/8));
-//	DbpString("All done");
+	
+	DbpString("Sim Stopped");
+	set_tracing(TRUE);
 }
 
 void ReaderHitag(hitag_function htf, hitag_data* htd) {
@@ -990,36 +1120,53 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
 	int t_wait = HITAG_T_WAIT_MAX;
 	bool bStop;
 	bool bQuitTraceFull = false;
-	
+  
+	FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
+	// Reset the return status
+	bSuccessful = false;
+  
 	// Clean up trace and prepare it for storing frames
-    iso14a_set_tracing(TRUE);
-    iso14a_clear_trace();
+	clear_trace();
+	set_tracing(TRUE);
+	
 	DbpString("Starting Hitag reader family");
 
 	// Check configuration
 	switch(htf) {
 		case RHT2F_PASSWORD: {
-            Dbprintf("List identifier in password mode");
+			Dbprintf("List identifier in password mode");
 			memcpy(password,htd->pwd.password,4);
-      blocknr = 0;
+      		blocknr = 0;
 			bQuitTraceFull = false;
 			bQuiet = false;
 			bPwd = false;
 		} break;
+      
 		case RHT2F_AUTHENTICATE: {
-			DbpString("Authenticating in crypto mode");
+			DbpString("Authenticating using nr,ar pair:");
 			memcpy(NrAr,htd->auth.NrAr,8);
-			Dbprintf("Reader-challenge:");
 			Dbhexdump(8,NrAr,false);
 			bQuiet = false;
 			bCrypto = false;
+			bAuthenticating = false;
+			bQuitTraceFull = true;
+		} break;
+      
+		case RHT2F_CRYPTO: {
+			DbpString("Authenticating using key:");
+			memcpy(key,htd->crypto.key,6);	  //HACK; 4 or 6??  I read both in the code.
+			Dbhexdump(6,key,false);
+			blocknr = 0;
+			bQuiet = false;
+			bCrypto = false;
+			bAuthenticating = false;
 			bQuitTraceFull = true;
 		} break;
 
 		case RHT2F_TEST_AUTH_ATTEMPTS: {
 			Dbprintf("Testing %d authentication attempts",(auth_table_len/8));
 			auth_table_pos = 0;
-			memcpy(NrAr,auth_table,8);
+			memcpy(NrAr, auth_table, 8);
 			bQuitTraceFull = false;
 			bQuiet = false;
 			bCrypto = false;
@@ -1027,6 +1174,7 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
 			
 		default: {
 			Dbprintf("Error, unknown function: %d",htf);
+			set_tracing(FALSE);
 			return;
 		} break;
 	}
@@ -1093,9 +1241,10 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
 		t_wait = HITAG_T_WAIT_2;
 		DbpString("Configured for hitag2 reader");
 	} else {
-        Dbprintf("Error, unknown hitag reader type: %d",htf);
-        return;
-    }
+		Dbprintf("Error, unknown hitag reader type: %d",htf);
+		set_tracing(FALSE);	
+		return;
+	}
 		
 	while(!bStop && !BUTTON_PRESS()) {
 		// Watchdog hit
@@ -1105,7 +1254,7 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
 		if(rxlen > 0) {
 			frame_count++;
 			if (!bQuiet) {
-				if (!LogTrace(rx,nbytes(rxlen),response,0,false)) {
+				if (!LogTraceHitag(rx,rxlen,response,0,false)) {
 					DbpString("Trace full");
 					if (bQuitTraceFull) {
 						break;
@@ -1125,11 +1274,15 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
 			case RHT2F_AUTHENTICATE: {
 				bStop = !hitag2_authenticate(rx,rxlen,tx,&txlen);
 			} break;
+			case RHT2F_CRYPTO: {
+				bStop = !hitag2_crypto(rx,rxlen,tx,&txlen);
+			} break;
 			case RHT2F_TEST_AUTH_ATTEMPTS: {
 				bStop = !hitag2_test_auth_attempts(rx,rxlen,tx,&txlen);
 			} break;
 			default: {
 				Dbprintf("Error, unknown function: %d",htf);
+				set_tracing(FALSE);
 				return;
 			} break;
 		}
@@ -1156,7 +1309,7 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
 			frame_count++;
 			if (!bQuiet) {
 				// Store the frame in the trace
-				if (!LogTrace(tx,nbytes(txlen),HITAG_T_WAIT_2,0,true)) {
+				if (!LogTraceHitag(tx,txlen,HITAG_T_WAIT_2,0,true)) {
 					if (bQuitTraceFull) {
 						break;
 					} else {
@@ -1237,7 +1390,7 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
 	AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
 	AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;
 	FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
-	
-//	Dbprintf("frame received: %d",frame_count);
-//	DbpString("All done");
-}
+	Dbprintf("DONE: frame received: %d",frame_count);
+	cmd_send(CMD_ACK,bSuccessful,0,0,(byte_t*)tag.sectors,48);
+  	set_tracing(FALSE);
+}
\ No newline at end of file