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

diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c
index d1005f3c..bc904c66 100644
--- a/armsrc/hitag2.c
+++ b/armsrc/hitag2.c
@@ -414,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
@@ -444,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);
@@ -698,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;
@@ -712,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);
 	
@@ -927,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);
 
@@ -1121,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) {
@@ -1149,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;
@@ -1166,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);
@@ -1224,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();
@@ -1249,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;
-					}
 				}
 			}
 		}
@@ -1275,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);
@@ -1321,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) {
@@ -1370,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;
@@ -1385,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