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

diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c
index 12bea2e5..bc904c66 100644
--- a/armsrc/hitag2.c
+++ b/armsrc/hitag2.c
@@ -94,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
@@ -103,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
@@ -116,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++)
 	{
@@ -129,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)
@@ -153,7 +152,7 @@ static u64 _hitag2_round (u64 *state)
 
 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;
@@ -415,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
@@ -445,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);
@@ -699,6 +698,42 @@ static bool hitag2_test_auth_attempts(byte_t* rx, const size_t rxlen, byte_t* tx
 	return true;
 }
 
+static bool hitag2_read_uid(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen) {
+	// Reset the transmission frame length
+	*txlen = 0;
+
+	// Try to find out which command was send by selecting on length (in bits)
+	switch (rxlen) {
+		// No answer, try to resurrect
+		case 0: {
+			// Just starting or if there is no answer
+			*txlen = 5;
+			memcpy(tx,"\xC0",nbytes(*txlen));
+		} break;
+		// Received UID
+		case 32: {
+			// 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 > 0) {
+				//DbpString("Read successful!");
+				bSuccessful = true;
+				return false;
+			}
+		} break;
+		// Unexpected response
+		default: {
+			Dbprintf("Uknown frame length: %d",rxlen);
+			return false;
+		} break;
+	}
+	return true;
+}
 
 void SnoopHitag(uint32_t type) {
 	int frame_count;
@@ -713,15 +748,17 @@ void SnoopHitag(uint32_t type) {
 	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
-	set_tracing(TRUE);
 	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);
 	
@@ -928,14 +965,17 @@ void SimulateHitagTag(bool tag_mem_supplied, byte_t* data) {
 	
 	FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
 
+	// free eventually allocated BigBuf memory
+	BigBuf_free(); BigBuf_Clear_ext(false);
+
 	// Clean up trace and prepare it for storing frames
-	set_tracing(TRUE);
 	clear_trace();
-
+	set_tracing(TRUE);
+	
 	auth_table_len = 0;
 	auth_table_pos = 0;
     byte_t* auth_table;
-	BigBuf_free();
+
     auth_table = (byte_t *)BigBuf_malloc(AUTH_TABLE_LENGTH);
 	memset(auth_table, 0x00, AUTH_TABLE_LENGTH);
 
@@ -1122,10 +1162,10 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
 	bSuccessful = false;
   
 	// Clean up trace and prepare it for storing frames
-	set_tracing(TRUE);
 	clear_trace();
-
-	DbpString("Starting Hitag reader family");
+	set_tracing(TRUE);
+	
+	//DbpString("Starting Hitag reader family");
 
 	// Check configuration
 	switch(htf) {
@@ -1150,7 +1190,7 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
       
 		case RHT2F_CRYPTO: {
 			DbpString("Authenticating using key:");
-			memcpy(key,htd->crypto.key,4);	  //HACK; 4 or 6??  I read both in the code.
+			memcpy(key,htd->crypto.key,6);	  //HACK; 4 or 6??  I read both in the code.
 			Dbhexdump(6,key,false);
 			blocknr = 0;
 			bQuiet = false;
@@ -1167,7 +1207,13 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
 			bQuiet = false;
 			bCrypto = false;
 		} break;
-			
+		case RHT2F_UID_ONLY: {
+			blocknr = 0;
+			bQuiet = false;
+			bCrypto = false;
+			bAuthenticating = false;
+			bQuitTraceFull = true;
+		} break;
 		default: {
 			Dbprintf("Error, unknown function: %d",htf);
 			set_tracing(FALSE);
@@ -1225,23 +1271,23 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
 		// hitagS settings
 		reset_sof = 1;
 		t_wait = 200;
-		DbpString("Configured for hitagS reader");
+    //DbpString("Configured for hitagS reader");
 	} else if (htf < 20) {
 		// hitag1 settings
 		reset_sof = 1;
 		t_wait = 200;
-		DbpString("Configured for hitag1 reader");
+    //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");
+    //DbpString("Configured for hitag2 reader");
 	} else {
 		Dbprintf("Error, unknown hitag reader type: %d",htf);
 		set_tracing(FALSE);	
 		return;
 	}
-		
+	uint8_t attempt_count=0;
 	while(!bStop && !BUTTON_PRESS()) {
 		// Watchdog hit
 		WDT_HIT();
@@ -1250,13 +1296,12 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
 		if(rxlen > 0) {
 			frame_count++;
 			if (!bQuiet) {
-				if (!LogTraceHitag(rx,rxlen,response,0,false)) {
+				if (!LogTraceHitag(rx,rxlen, response, 0, false)) {
 					DbpString("Trace full");
-					if (bQuitTraceFull) {
+					if (bQuitTraceFull)
 						break;
-					} else {
+					else
 						bQuiet = true;
-					}
 				}
 			}
 		}
@@ -1276,6 +1321,11 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
 			case RHT2F_TEST_AUTH_ATTEMPTS: {
 				bStop = !hitag2_test_auth_attempts(rx,rxlen,tx,&txlen);
 			} break;
+			case RHT2F_UID_ONLY: {
+				bStop = !hitag2_read_uid(rx, rxlen, tx, &txlen);
+				attempt_count++; //attempt 3 times to get uid then quit
+				if (!bStop && attempt_count == 3) bStop = true;
+			} break;
 			default: {
 				Dbprintf("Error, unknown function: %d",htf);
 				set_tracing(FALSE);
@@ -1322,6 +1372,8 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
 		bSkip = true;
 		tag_sof = reset_sof;
 		response = 0;
+			//Dbprintf("DEBUG: Waiting to receive frame");
+		uint32_t errorCount = 0;
 		
 		// Receive frame, watch for at most T0*EOF periods
 		while (AT91C_BASE_TC1->TC_CV < T0*HITAG_T_WAIT_MAX) {
@@ -1371,10 +1423,13 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
 						rxlen++;
 					}
 				} else {
+						//Dbprintf("DEBUG: Wierd2");
+						errorCount++;
 					// Ignore wierd value, is to small to mean anything
 				}
 			}
-
+			//if we saw over 100 wierd values break it probably isn't hitag...
+			if (errorCount >100) break;
 			// We can break this loop if we received the last bit from a frame
 			if (AT91C_BASE_TC1->TC_CV > T0*HITAG_T_EOF) {
 				if (rxlen>0) break;
@@ -1386,7 +1441,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("DONE: frame received: %d",frame_count);
+//	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