From 04202e7aa76dd9f0628d8245ae01fd224e5fbf17 Mon Sep 17 00:00:00 2001
From: douniwan5788 <douniwan5788@ef4ab9da-24cd-11de-8aaa-f3a34680c41f>
Date: Tue, 5 Feb 2013 10:03:53 +0000
Subject: [PATCH] Add iso14443a fuzz command

---
 armsrc/iso14443a.c | 17 ++++++++++--
 client/cmdhf14a.c  | 66 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 81 insertions(+), 2 deletions(-)

diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c
index 3757043b..780a7ca0 100644
--- a/armsrc/iso14443a.c
+++ b/armsrc/iso14443a.c
@@ -1770,6 +1770,7 @@ void ReaderIso14443a(UsbCommand * c, UsbCommand * ack)
 	iso14a_command_t param = c->arg[0];
 	uint8_t * cmd = c->d.asBytes;
 	size_t len = c->arg[1];
+	uint8_t *receiveBuf = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET);
 
 	if(param & ISO14A_REQUEST_TRIGGER) iso14a_set_trigger(1);
 
@@ -1788,7 +1789,19 @@ void ReaderIso14443a(UsbCommand * c, UsbCommand * ack)
 	}
 
 	if(param & ISO14A_APDU) {
-		ack->arg[0] = iso14_apdu(cmd, len, ack->d.asBytes);
+  	memcpy(receiveBuf, ack->d.asBytes, len);
+		ack->arg[0] = iso14_apdu(cmd, len, receiveBuf);
+		
+    while(ack->arg[0] > sizeof(ack->d))
+    {
+      memcpy(ack->d.asBytes, receiveBuf, sizeof(ack->d));  		
+  		UsbSendPacket((void *)ack, sizeof(UsbCommand));
+
+      receiveBuf+=sizeof(ack->d);
+  		ack->arg[0]-=sizeof(ack->d);
+		}
+		
+		memcpy(ack->d.asBytes, receiveBuf, ack->arg[0]);
 		UsbSendPacket((void *)ack, sizeof(UsbCommand));
 	}
 
@@ -2513,4 +2526,4 @@ done:
 	
 	Dbprintf("maxDataLen=%x, Uart.state=%x, Uart.byteCnt=%x Uart.byteCntMax=%x", maxDataLen, Uart.state, Uart.byteCnt, Uart.byteCntMax);
 	LEDsoff();
-}
\ No newline at end of file
+}
diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c
index be7afc77..6e94006e 100644
--- a/client/cmdhf14a.c
+++ b/client/cmdhf14a.c
@@ -22,6 +22,7 @@
 #include "cmdhf14a.h"
 #include "common.h"
 #include "cmdmain.h"
+#include "sleep.h"
 
 static int CmdHelp(const char *Cmd);
 
@@ -160,6 +161,22 @@ void iso14a_set_timeout(uint32_t timeout) {
 int CmdHF14AReader(const char *Cmd)
 {
 	UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT, 0, 0}};
+	char param[256]={0};
+	
+	if( 3 == param_getstr(Cmd,0,param) && !strcmp("con",param))
+	{
+	  c.arg[0]|=ISO14A_NO_DISCONNECT;
+		PrintAndLog("KEEP connected!\n");
+	}
+	
+	if( 3 == param_getstr(Cmd,0,param) && !strcmp("dis",param))
+	{
+	  c.arg[0] = 0;
+		PrintAndLog("disconnected!\n");
+		SendCommand(&c);
+		return 0;
+	}
+	
 	SendCommand(&c);
 	UsbCommand * resp = WaitForResponse(CMD_ACK);
 	uint8_t              * uid  = resp->d.asBytes;
@@ -461,6 +478,54 @@ int CmdHF14ASnoop(const char *Cmd) {
   return 0;
 }
 
+int CmdHF14AFuzz(const char *Cmd) {
+  char  formatstr[256] = {0},sendbuf[256] = {0};
+  uint32_t   start=0,end=0;
+
+  if (param_getchar(Cmd, 0) == 0) {
+	  PrintAndLog("fuzz raw hex data to the card and show response <ONLY for develepers>");
+	  PrintAndLog("Usage:  hf 14a fuzz <FORMAT> [<start index> <end index>]");
+	  PrintAndLog("FORMAT controls the output as in C printf");
+	  PrintAndLog("sample: hf 14a fuzz 909F");
+	  PrintAndLog("        hf 14a fuzz 00%02x00000000 0 0xFF");
+	  return 0;
+  }
+
+  start  = param_get8ex(Cmd, 1, 0,16);
+  end    = param_get8ex(Cmd, 2, 0,16);
+  param_getstr(Cmd, 0, formatstr);  
+  
+  for( int i=start;i<=end;++i)
+  {
+    snprintf(sendbuf, sizeof(sendbuf), formatstr, i);
+    
+    int len = strlen(sendbuf)/2;
+    
+	  UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_APDU|ISO14A_NO_DISCONNECT, len, 0}};
+    param_gethex(sendbuf, 0, c.d.asBytes, len*2);
+    PrintAndLog("len:%d raw:",len);	
+	  PrintAndLog("%s",sprint_hex(c.d.asBytes, len));
+	  SendCommand(&c);
+    
+    UsbCommand * resp = WaitForResponse(CMD_ACK);
+    PrintAndLog("res:%d",resp->arg[0]);
+    
+    while(resp->arg[0] > sizeof(resp->d))
+    {
+      PrintAndLog("%s", sprint_hex(resp->d.asBytes,sizeof(resp->d)));
+      
+      resp = WaitForResponse(CMD_ACK);
+    }
+    PrintAndLog("%s", sprint_hex(resp->d.asBytes,resp->arg[0]));
+    
+    PrintAndLog("");
+    
+    msleep(100);
+  }
+  
+  return 0;
+}
+
 static command_t CommandTable[] = 
 {
   {"help",   CmdHelp,              1, "This help"},
@@ -469,6 +534,7 @@ static command_t CommandTable[] =
   {"cuids",  CmdHF14ACUIDs,        0, "<n> Collect n>0 ISO14443 Type A UIDs in one go"},
   {"sim",    CmdHF14ASim,          0, "<UID> -- Fake ISO 14443a tag"},
   {"snoop",  CmdHF14ASnoop,        0, "Eavesdrop ISO 14443 Type A"},
+  {"fuzz",   CmdHF14AFuzz,         0, "Fuzz"},
   {NULL, NULL, 0, NULL}
 };
 
-- 
2.39.5