X-Git-Url: http://cvs.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/8258f409697ab41a6858ef9bdcdf406989223bbb..refs/pull/130/head:/armsrc/appmain.c?ds=sidebyside

diff --git a/armsrc/appmain.c b/armsrc/appmain.c
index 7b94f8a3..40df5f5f 100644
--- a/armsrc/appmain.c
+++ b/armsrc/appmain.c
@@ -29,6 +29,11 @@
  #include "LCD.h"
 #endif
 
+// Craig Young - 14a stand-alone code
+#ifdef WITH_ISO14443a_StandAlone
+ #include "iso14443a.h"
+#endif
+
 #define abs(x) ( ((x)<0) ? -(x) : (x) )
 
 //=============================================================================
@@ -250,55 +255,6 @@ void MeasureAntennaTuningHf(void)
 }
 
 
-void SimulateTagHfListen(void)
-{
-	// ToDo: historically this used the free buffer, which was 2744 Bytes long. 
-	// There might be a better size to be defined:
-	#define HF_14B_SNOOP_BUFFER_SIZE 2744
-	uint8_t *dest = BigBuf_malloc(HF_14B_SNOOP_BUFFER_SIZE);
-	uint8_t v = 0;
-	int i;
-	int p = 0;
-
-	// We're using this mode just so that I can test it out; the simulated
-	// tag mode would work just as well and be simpler.
-	FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
-	FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ | FPGA_HF_READER_RX_XCORR_SNOOP);
-
-	// We need to listen to the high-frequency, peak-detected path.
-	SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
-
-	FpgaSetupSsc();
-
-	i = 0;
-	for(;;) {
-		if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
-			AT91C_BASE_SSC->SSC_THR = 0xff;
-		}
-		if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
-			uint8_t r = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
-
-			v <<= 1;
-			if(r & 1) {
-				v |= 1;
-			}
-			p++;
-
-			if(p >= 8) {
-				dest[i] = v;
-				v = 0;
-				p = 0;
-				i++;
-
-				if(i >= HF_14B_SNOOP_BUFFER_SIZE) {
-					break;
-				}
-			}
-		}
-	}
-	DbpString("simulate tag (now type bitsamples)");
-}
-
 void ReadMem(int addr)
 {
 	const uint8_t *data = ((uint8_t *)addr);
@@ -310,11 +266,11 @@ void ReadMem(int addr)
 /* osimage version information is linked in */
 extern struct version_information version_information;
 /* bootrom version information is pointed to from _bootphase1_version_pointer */
-extern char *_bootphase1_version_pointer, _flash_start, _flash_end;
+extern char *_bootphase1_version_pointer, _flash_start, _flash_end, _bootrom_start, _bootrom_end, __data_src_start__;
 void SendVersion(void)
 {
-	char temp[512]; /* Limited data payload in USB packets */
-	DbpString("Prox/RFID mark3 RFID instrument");
+	char temp[USB_CMD_DATA_SIZE]; /* Limited data payload in USB packets */
+	char VersionString[USB_CMD_DATA_SIZE] = { '\0' };
 
 	/* Try to find the bootrom version information. Expect to find a pointer at
 	 * symbol _bootphase1_version_pointer, perform slight sanity checks on the
@@ -322,22 +278,28 @@ void SendVersion(void)
 	 */
 	char *bootrom_version = *(char**)&_bootphase1_version_pointer;
 	if( bootrom_version < &_flash_start || bootrom_version >= &_flash_end ) {
-		DbpString("bootrom version information appears invalid");
+		strcat(VersionString, "bootrom version information appears invalid\n");
 	} else {
 		FormatVersionInformation(temp, sizeof(temp), "bootrom: ", bootrom_version);
-		DbpString(temp);
+		strncat(VersionString, temp, sizeof(VersionString) - strlen(VersionString) - 1);
 	}
 
 	FormatVersionInformation(temp, sizeof(temp), "os: ", &version_information);
-	DbpString(temp);
+	strncat(VersionString, temp, sizeof(VersionString) - strlen(VersionString) - 1);
 
-	FpgaGatherVersion(temp, sizeof(temp));
-	DbpString(temp);
-	// Send Chip ID
-	cmd_send(CMD_ACK,*(AT91C_DBGU_CIDR),0,0,NULL,0);
+	FpgaGatherVersion(FPGA_BITSTREAM_LF, temp, sizeof(temp));
+	strncat(VersionString, temp, sizeof(VersionString) - strlen(VersionString) - 1);
+	FpgaGatherVersion(FPGA_BITSTREAM_HF, temp, sizeof(temp));
+	strncat(VersionString, temp, sizeof(VersionString) - strlen(VersionString) - 1);
+
+	// Send Chip ID and used flash memory
+	uint32_t text_and_rodata_section_size = (uint32_t)&__data_src_start__ - (uint32_t)&_flash_start;
+	uint32_t compressed_data_section_size = common_area.arg1;
+	cmd_send(CMD_ACK, *(AT91C_DBGU_CIDR), text_and_rodata_section_size + compressed_data_section_size, 0, VersionString, strlen(VersionString));
 }
 
 #ifdef WITH_LF
+#ifndef WITH_ISO14443a_StandAlone
 // samy's sniff and repeat routine
 void SamyRun()
 {
@@ -484,7 +446,219 @@ void SamyRun()
 	}
 }
 #endif
+#endif
+#ifdef WITH_ISO14443a
+#ifdef WITH_ISO14443a_StandAlone
+void StandAloneMode14a()
+{
+	DbpString("Stand-alone mode! No PC necessary.");
+	FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
+
+	// 3 possible options? no just 1 for now
+#undef OPTS
+#define OPTS 2
+	// Oooh pretty -- notify user we're in elite samy mode now
+	LED(LED_RED,	200);
+	LED(LED_ORANGE, 200);
+	LED(LED_GREEN,	200);
+	LED(LED_ORANGE, 200);
+	LED(LED_RED,	200);
+	LED(LED_ORANGE, 200);
+	LED(LED_GREEN,	200);
+	LED(LED_ORANGE, 200);
+	LED(LED_RED,	200);
+
+	int selected = 0;
+	int playing = 0;
+	int cardRead[OPTS] = {0};
+	uint8_t readUID[10] = {0};
+	int uid_1st[OPTS]={0};
+	int uid_2nd[OPTS]={0};
+
+	LED(selected + 1, 0);
+
+	for (;;)
+	{
+		usb_poll();
+    WDT_HIT();
+
+		// Was our button held down or pressed?
+		int button_pressed = BUTTON_HELD(1000);
+
+		SpinDelay(300);
+
+		// Button was held for a second, begin recording
+		if (button_pressed > 0 && cardRead[selected] == 0)
+		{
+			LEDsoff();
+			LED(selected + 1, 0);
+			LED(LED_RED2, 0);
+
+			// record
+			Dbprintf("Enabling iso14443a reader mode for [Bank: %u]...", selected);
+
+			// wait for button to be released
+			while(BUTTON_PRESS())
+				WDT_HIT();
+			/* need this delay to prevent catching some weird data */
+			SpinDelay(500);
+			/* Code for reading from 14a tag */
+			uint8_t uid[10]  ={0};
+			uint32_t cuid;
+			iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD);
+
+			for ( ; ; )
+			{
+				if (!iso14443a_select_card(uid, NULL, &cuid))
+					continue;
+				else
+				{
+					Dbprintf("Read UID:"); Dbhexdump(10,uid,0);
+					memcpy(readUID,uid,10*sizeof(uint8_t));
+					uint8_t *dst = (uint8_t *)&uid_1st[selected];
+					// Set UID byte order 
+					for (int i=0; i<4; i++)
+						dst[i] = uid[3-i];
+					dst = (uint8_t *)&uid_2nd[selected];
+					for (int i=0; i<4; i++)
+						dst[i] = uid[7-i];
+					break;
+				}
+			} 
+			LEDsoff();
+                        LED(LED_GREEN,  200);
+                        LED(LED_ORANGE, 200);
+                        LED(LED_GREEN,  200);
+                        LED(LED_ORANGE, 200);
+			
+			LEDsoff();
+			LED(selected + 1, 0);
+			// Finished recording
+
+			// If we were previously playing, set playing off
+			// so next button push begins playing what we recorded
+			playing = 0;
+			
+			cardRead[selected] = 1;
+	
+		}
+/* MF UID clone */
+		else if (button_pressed > 0 && cardRead[selected] == 1)
+		{
+					LEDsoff();
+					LED(selected + 1, 0);
+					LED(LED_ORANGE, 250);
+
+
+					// record
+					Dbprintf("Preparing to Clone card [Bank: %x]; uid: %08x", selected, uid_1st[selected]);
+
+					// wait for button to be released
+					while(BUTTON_PRESS())
+						{ 
+						// Delay cloning until card is in place
+						WDT_HIT();
+						}
+					Dbprintf("Starting clone. [Bank: %u]", selected);
+					// need this delay to prevent catching some weird data
+					SpinDelay(500);
+					// Begin clone function here:
+					/* Example from client/mifarehost.c for commanding a block write for "magic Chinese" cards:
+							UsbCommand c = {CMD_MIFARE_CSETBLOCK, {wantWipe, params & (0xFE | (uid == NULL ? 0:1)), blockNo}};
+	        				memcpy(c.d.asBytes, data, 16);
+	        				SendCommand(&c);
+
+        				Block read is similar:
+        					UsbCommand c = {CMD_MIFARE_CGETBLOCK, {params, 0, blockNo}};
+        				We need to imitate that call with blockNo 0 to set a uid.
+
+        				The get and set commands are handled in this file:
+			        		// Work with "magic Chinese" card
+			                case CMD_MIFARE_CSETBLOCK:
+			                        MifareCSetBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
+			                        break;
+			                case CMD_MIFARE_CGETBLOCK:
+			                        MifareCGetBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
+			                        				// 
+			                        break;	
+
+						mfCSetUID provides example logic for UID set workflow:
+							-Read block0 from card in field with MifareCGetBlock()
+							-Configure new values without replacing reserved bytes
+							        memcpy(block0, uid, 4); // Copy UID bytes from byte array
+        							// Mifare UID BCC
+        							block0[4] = block0[0]^block0[1]^block0[2]^block0[3]; // BCC on byte 5
+        							Bytes 5-7 are reserved SAK and ATQA for mifare classic
+        					-Use mfCSetBlock(0, block0, oldUID, wantWipe, CSETBLOCK_SINGLE_OPER) to write it
+        			*/
+        			uint8_t oldBlock0[16] = {0}, newBlock0[16] = {0}, testBlock0[16] = {0};
+        			// arg0 = Flags == CSETBLOCK_SINGLE_OPER=0x1F, arg1=returnSlot, arg2=blockNo 
+        			MifareCGetBlock(0x1F, 1, 0, oldBlock0);
+        			Dbprintf("UID from target tag: %02X%02X%02X%02X", oldBlock0[0],oldBlock0[1],oldBlock0[2],oldBlock0[3]);
+        			memcpy(newBlock0,oldBlock0,16);
+        			// Copy uid_1st for bank (2nd is for longer UIDs not supported if classic)
+        			newBlock0[0] = uid_1st[selected]>>24;
+        			newBlock0[1] = 0xFF & (uid_1st[selected]>>16);
+        			newBlock0[2] = 0xFF & (uid_1st[selected]>>8);
+        			newBlock0[3] = 0xFF & (uid_1st[selected]);
+        			newBlock0[4] = newBlock0[0]^newBlock0[1]^newBlock0[2]^newBlock0[3];
+        			// arg0 = needWipe, arg1 = workFlags, arg2 = blockNo, datain
+        			MifareCSetBlock(0, 0xFF,0, newBlock0);
+        			MifareCGetBlock(0x1F, 1, 0, testBlock0);
+        			if (memcmp(testBlock0,newBlock0,16)==0)
+        			{
+        				DbpString("Cloned successfull!");
+        				cardRead[selected] = 0; // Only if the card was cloned successfully should we clear it
+        			}
+					LEDsoff();
+					LED(selected + 1, 0);
+					// Finished recording
+
+					// If we were previously playing, set playing off
+					// so next button push begins playing what we recorded
+					playing = 0;
+			
+		}
+		// Change where to record (or begin playing)
+		else if (button_pressed && cardRead[selected])
+		{
+			// Next option if we were previously playing
+			if (playing)
+				selected = (selected + 1) % OPTS;
+			playing = !playing;
 
+			LEDsoff();
+			LED(selected + 1, 0);
+
+			// Begin transmitting
+			if (playing)
+			{
+				LED(LED_GREEN, 0);
+				DbpString("Playing");
+	            while (!BUTTON_HELD(500)) { // Loop simulating tag until the button is held a half-sec
+        	            Dbprintf("Simulating ISO14443a tag with uid[0]: %08x, uid[1]: %08x [Bank: %u]", uid_1st[selected],uid_2nd[selected],selected);
+				        SimulateIso14443aTag(1,uid_1st[selected],uid_2nd[selected],NULL);	
+					}
+				//cardRead[selected] = 1; 
+				Dbprintf("Done playing [Bank: %u]",selected);
+
+				/* We pressed a button so ignore it here with a delay */
+				SpinDelay(300);
+
+				// when done, we're done playing, move to next option
+				selected = (selected + 1) % OPTS;
+				playing = !playing;
+				LEDsoff();
+				LED(selected + 1, 0);
+			}
+			else 
+				while(BUTTON_PRESS())
+					WDT_HIT();
+		}
+	}
+}
+#endif
+#endif
 /*
 OBJECTIVE
 Listen and detect an external reader. Determine the best location
@@ -725,6 +899,9 @@ void UsbPacketReceived(uint8_t *packet, int len)
 		case CMD_EM4X_WRITE_WORD:
 			EM4xWriteWord(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes[0]);
 			break;
+		case CMD_AWID_DEMOD_FSK: // Set realtime AWID demodulation
+			CmdAWIDdemodFSK(c->arg[0], 0, 0, 1);
+                        break;
 #endif
 
 #ifdef WITH_HITAG
@@ -782,20 +959,17 @@ void UsbPacketReceived(uint8_t *packet, int len)
 #endif
 
 #ifdef WITH_ISO14443b
-		case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443:
-			AcquireRawAdcSamplesIso14443(c->arg[0]);
-			break;
 		case CMD_READ_SRI512_TAG:
-			ReadSTMemoryIso14443(0x0F);
+			ReadSTMemoryIso14443b(0x0F);
 			break;
 		case CMD_READ_SRIX4K_TAG:
-			ReadSTMemoryIso14443(0x7F);
+			ReadSTMemoryIso14443b(0x7F);
 			break;
-		case CMD_SNOOP_ISO_14443:
-			SnoopIso14443();
+		case CMD_SNOOP_ISO_14443B:
+			SnoopIso14443b();
 			break;
-		case CMD_SIMULATE_TAG_ISO_14443:
-			SimulateIso14443Tag();
+		case CMD_SIMULATE_TAG_ISO_14443B:
+			SimulateIso14443bTag();
 			break;
 		case CMD_ISO_14443B_COMMAND:
 			SendRawCommand14443B(c->arg[0],c->arg[1],c->arg[2],c->d.asBytes);
@@ -816,6 +990,9 @@ void UsbPacketReceived(uint8_t *packet, int len)
 		case CMD_EPA_PACE_COLLECT_NONCE:
 			EPA_PACE_Collect_Nonce(c);
 			break;
+		case CMD_EPA_PACE_REPLAY:
+			EPA_PACE_Replay(c);
+			break;
 			
 		case CMD_READER_MIFARE:
 			ReaderMifare(c->arg[0]);
@@ -830,7 +1007,6 @@ void UsbPacketReceived(uint8_t *packet, int len)
 			MifareUC_Auth(c->arg[0],c->d.asBytes);
 			break;
 		case CMD_MIFAREU_READCARD:
-		case CMD_MIFAREUC_READCARD:
 			MifareUReadCard(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
 			break;
 		case CMD_MIFAREUC_SETPWD: 
@@ -842,11 +1018,11 @@ void UsbPacketReceived(uint8_t *packet, int len)
 		case CMD_MIFARE_WRITEBL:
 			MifareWriteBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
 			break;
-		case CMD_MIFAREU_WRITEBL_COMPAT:
-			MifareUWriteBlock(c->arg[0], c->d.asBytes);
-			break;
+		//case CMD_MIFAREU_WRITEBL_COMPAT:
+			//MifareUWriteBlockCompat(c->arg[0], c->d.asBytes);
+			//break;
 		case CMD_MIFAREU_WRITEBL:
-			MifareUWriteBlock_Special(c->arg[0], c->d.asBytes);
+			MifareUWriteBlock(c->arg[0], c->arg[1], c->d.asBytes);
 			break;
 		case CMD_MIFARE_NESTED:
 			MifareNested(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
@@ -912,10 +1088,6 @@ void UsbPacketReceived(uint8_t *packet, int len)
 			break;
 #endif
 
-		case CMD_SIMULATE_TAG_HF_LISTEN:
-			SimulateTagHfListen();
-			break;
-
 		case CMD_BUFF_CLEAR:
 			BigBuf_Clear();
 			break;
@@ -1077,8 +1249,16 @@ void  __attribute__((noreturn)) AppMain(void)
 		WDT_HIT();
 
 #ifdef WITH_LF
+#ifndef WITH_ISO14443a_StandAlone
 		if (BUTTON_HELD(1000) > 0)
 			SamyRun();
+#endif
+#endif
+#ifdef WITH_ISO14443a
+#ifdef WITH_ISO14443a_StandAlone
+		if (BUTTON_HELD(1000) > 0)
+			StandAloneMode14a();
+#endif
 #endif
 	}
 }