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

diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c
index 2d064565..1147cb8d 100644
--- a/armsrc/hitag2.c
+++ b/armsrc/hitag2.c
@@ -16,22 +16,19 @@
 // (c) 2012 Roel Verdult
 //-----------------------------------------------------------------------------
 
-#include "../include/proxmark3.h"
+#include "proxmark3.h"
 #include "apps.h"
 #include "util.h"
-#include "../include/hitag2.h"
+#include "hitag2.h"
 #include "string.h"
 #include "BigBuf.h"
 
 static bool bQuiet;
-
 static bool bCrypto;
 static bool bAuthenticating;
 static bool bPwd;
 static bool bSuccessful;
 
-
-
 struct hitag2_tag {
 	uint32_t uid;
 	enum {
@@ -97,7 +94,6 @@ static uint64_t cipher_state;
 #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
@@ -106,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
@@ -119,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++)
 	{
@@ -132,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)
@@ -144,24 +140,31 @@ 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;
 }
 
-static int hitag2_reset(void)
-{
+static int hitag2_reset(void) {
 	tag.state = TAG_STATE_RESET;
 	tag.crypto_active = 0;
 	return 0;
 }
 
-static int hitag2_init(void)
-{
-//	memcpy(&tag, &resetdata, sizeof(tag));
+static int hitag2_init(void) {
 	hitag2_reset();
 	return 0;
 }
@@ -223,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 
 
@@ -424,11 +427,10 @@ 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();
 }
@@ -475,26 +477,26 @@ static bool hitag2_password(byte_t* rx, const size_t rxlen, byte_t* tx, size_t*
 				*txlen = 32;
 				memcpy(tx,password,4);
 				bPwd = true;
-        memcpy(tag.sectors[blocknr],rx,4);
-        blocknr++;
+				memcpy(tag.sectors[blocknr],rx,4);
+				blocknr++;
 			} else {
 				
-			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);
+				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;
 			
@@ -544,9 +546,9 @@ static bool hitag2_crypto(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* tx
           bCrypto = false;
         }
 			} else {
-        *txlen = 5;
-        memcpy(tx,"\xc0",nbytes(*txlen));
-      }
+				*txlen = 5;
+				memcpy(tx,"\xc0",nbytes(*txlen));
+			}
 		} break;
 			
       // Received UID, crypto tag answer
@@ -560,20 +562,20 @@ static bool hitag2_crypto(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* tx
         hitag2_cipher_transcrypt(&cipher_state,tx+4,4,0);
 				*txlen = 64;
 				bCrypto = true;
-        bAuthenticating = true;
+				bAuthenticating = true;
 			} else {
         // Check if we received answer tag (at)
         if (bAuthenticating) {
-          bAuthenticating = false;
+			bAuthenticating = false;
         } else {
-          // Store the received block
-          memcpy(tag.sectors[blocknr],rx,4);
-          blocknr++;
+			// Store the received block
+			memcpy(tag.sectors[blocknr],rx,4);
+			blocknr++;
         }
         if (blocknr > 7) {
-          DbpString("Read succesful!");
-          bSuccessful = true;
-          return false;
+			DbpString("Read succesful!");
+			bSuccessful = true;
+			return false;
         }
         *txlen = 10;
         tx[0] = 0xc0 | (blocknr << 3) | ((blocknr^7) >> 2);
@@ -589,11 +591,11 @@ static bool hitag2_crypto(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* tx
 	}
 	
   
-  if(bCrypto) {
-    // We have to return now to avoid double encryption
-    if (!bAuthenticating) {
-      hitag2_cipher_transcrypt(&cipher_state,tx,*txlen/8,*txlen%8);
-    }
+	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;
@@ -625,8 +627,7 @@ static bool hitag2_authenticate(byte_t* rx, const size_t rxlen, byte_t* tx, size
 				bCrypto = true;
 			} else {
 				DbpString("Authentication succesful!");
-				// We are done... for now
-				return false;
+				return true;
 			}
 		} break;
 			
@@ -710,22 +711,24 @@ void SnoopHitag(uint32_t type) {
 	byte_t rx[HITAG_FRAME_LEN];
 	size_t rxlen=0;
 	
+	FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
+
+	// Clean up trace and prepare it for storing frames
+	clear_trace();
+	set_tracing(TRUE);
+	
 	auth_table_len = 0;
 	auth_table_pos = 0;
+
 	BigBuf_free();
     auth_table = (byte_t *)BigBuf_malloc(AUTH_TABLE_LENGTH);
 	memset(auth_table, 0x00, AUTH_TABLE_LENGTH);
-
-	// Clean up trace and prepare it for storing frames
-	set_tracing(TRUE);
-	clear_trace();
 	
 	DbpString("Starting Hitag2 snoop");
 	LED_D_ON();
 	
 	// Set up eavesdropping mode, frequency divisor which will drive the FPGA
 	// and analog mux selection.
-	FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
 	FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT  | FPGA_LF_EDGE_DETECT_TOGGLE_MODE);
 	FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
 	SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
@@ -763,7 +766,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();
 		
@@ -905,7 +908,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");
@@ -922,6 +925,12 @@ void SimulateHitagTag(bool tag_mem_supplied, byte_t* data) {
 	bool bQuitTraceFull = false;
 	bQuiet = false;
 	
+	FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
+
+	// Clean up trace and prepare it for storing frames
+	clear_trace();
+	set_tracing(TRUE);
+	
 	auth_table_len = 0;
 	auth_table_pos = 0;
     byte_t* auth_table;
@@ -929,10 +938,6 @@ void SimulateHitagTag(bool tag_mem_supplied, byte_t* data) {
     auth_table = (byte_t *)BigBuf_malloc(AUTH_TABLE_LENGTH);
 	memset(auth_table, 0x00, AUTH_TABLE_LENGTH);
 
-	// Clean up trace and prepare it for storing frames
-	set_tracing(TRUE);
-	clear_trace();
-
 	DbpString("Starting Hitag2 simulation");
 	LED_D_ON();
 	hitag2_init();
@@ -953,7 +958,6 @@ void SimulateHitagTag(bool tag_mem_supplied, byte_t* data) {
 	
 	// Set up simulator mode, frequency divisor which will drive the FPGA
 	// and analog mux selection.
-	FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
 	FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD);
 	FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
 	SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
@@ -989,7 +993,7 @@ void SimulateHitagTag(bool tag_mem_supplied, byte_t* data) {
 	// 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();
 		
@@ -1093,7 +1097,7 @@ void SimulateHitagTag(bool tag_mem_supplied, byte_t* data) {
 	FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
 	
 	DbpString("Sim Stopped");
-	
+	set_tracing(TRUE);
 }
 
 void ReaderHitag(hitag_function htf, hitag_data* htd) {
@@ -1117,9 +1121,9 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
 	bSuccessful = false;
   
 	// Clean up trace and prepare it for storing frames
-	set_tracing(TRUE);
 	clear_trace();
-
+	set_tracing(TRUE);
+	
 	DbpString("Starting Hitag reader family");
 
 	// Check configuration
@@ -1165,6 +1169,7 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
 			
 		default: {
 			Dbprintf("Error, unknown function: %d",htf);
+			set_tracing(FALSE);
 			return;
 		} break;
 	}
@@ -1214,26 +1219,27 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
 	lastbit = 1;
 	bStop = false;
 
-  // Tag specific configuration settings (sof, timings, etc.)
-  if (htf < 10){
-    // hitagS settings
-    reset_sof = 1;
-    t_wait = 200;
-    DbpString("Configured for hitagS reader");
-  } else if (htf < 20) {
-    // hitag1 settings
-    reset_sof = 1;
-    t_wait = 200;
-    DbpString("Configured for hitag1 reader");
-  } else if (htf < 30) {
-    // hitag2 settings
-    reset_sof = 4;
-    t_wait = HITAG_T_WAIT_2;
-    DbpString("Configured for hitag2 reader");
+	// Tag specific configuration settings (sof, timings, etc.)
+	if (htf < 10){
+		// hitagS settings
+		reset_sof = 1;
+		t_wait = 200;
+		DbpString("Configured for hitagS reader");
+	} else if (htf < 20) {
+		// hitag1 settings
+		reset_sof = 1;
+		t_wait = 200;
+		DbpString("Configured for hitag1 reader");
+	} else if (htf < 30) {
+		// hitag2 settings
+		reset_sof = 4;
+		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
@@ -1271,6 +1277,7 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
 			} break;
 			default: {
 				Dbprintf("Error, unknown function: %d",htf);
+				set_tracing(FALSE);
 				return;
 			} break;
 		}
@@ -1378,7 +1385,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");
-  cmd_send(CMD_ACK,bSuccessful,0,0,(byte_t*)tag.sectors,48);
-}
+	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