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

diff --git a/armsrc/appmain.c b/armsrc/appmain.c
index fb3c0f18..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) )
 
 //=============================================================================
@@ -261,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
@@ -273,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()
 {
@@ -435,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
@@ -676,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
@@ -764,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]);
@@ -1020,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
 	}
 }