X-Git-Url: http://cvs.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/ef00343cb1f6ab306020c4108cd414e8df6b132f..c83d6dc6fa3f266ace020cb90eb5df0e3e81e022:/client/cmdhf.c?ds=inline

diff --git a/client/cmdhf.c b/client/cmdhf.c
index 960dcf7f..17353fb6 100644
--- a/client/cmdhf.c
+++ b/client/cmdhf.c
@@ -11,8 +11,10 @@
 #include <stdio.h>
 #include <string.h>
 #include "proxmark3.h"
-#include "graph.h"
+#include "util.h"
 #include "ui.h"
+#include "iso14443crc.h"
+#include "cmdmain.h"
 #include "cmdparser.h"
 #include "cmdhf.h"
 #include "cmdhf14a.h"
@@ -23,6 +25,7 @@
 #include "cmdhficlass.h"
 #include "cmdhfmf.h"
 #include "cmdhfmfu.h"
+#include "cmdhftopaz.h"
 #include "protocols.h"
 
 static int CmdHelp(const char *Cmd);
@@ -71,11 +74,57 @@ void annotateIso14443a(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize)
 	case MIFARE_CMD_DEC:			snprintf(exp,size,"DEC(%d)",cmd[1]); break;
 	case MIFARE_CMD_RESTORE:		snprintf(exp,size,"RESTORE(%d)",cmd[1]); break;
 	case MIFARE_CMD_TRANSFER:		snprintf(exp,size,"TRANSFER(%d)",cmd[1]); break;
-	case MIFARE_AUTH_KEYA:			snprintf(exp,size,"AUTH-A(%d)",cmd[1]); break;
+	case MIFARE_AUTH_KEYA:{
+		if ( cmdsize > 3)
+			snprintf(exp,size,"AUTH-A(%d)",cmd[1]); 
+		else
+			//	case MIFARE_ULEV1_VERSION :  both 0x60.
+			snprintf(exp,size,"EV1 VERSION");
+		break;
+	}
 	case MIFARE_AUTH_KEYB:			snprintf(exp,size,"AUTH-B(%d)",cmd[1]); break;
 	case MIFARE_MAGICWUPC1:			snprintf(exp,size,"MAGIC WUPC1"); break;
 	case MIFARE_MAGICWUPC2:			snprintf(exp,size,"MAGIC WUPC2"); break;
 	case MIFARE_MAGICWIPEC:			snprintf(exp,size,"MAGIC WIPEC"); break;
+	case MIFARE_ULC_AUTH_1:		snprintf(exp,size,"AUTH "); break;
+	case MIFARE_ULC_AUTH_2:		snprintf(exp,size,"AUTH_ANSW"); break;
+	case MIFARE_ULEV1_AUTH:
+		if ( cmdsize == 7 )
+			snprintf(exp,size,"PWD-AUTH KEY: 0x%02x%02x%02x%02x", cmd[1], cmd[2], cmd[3], cmd[4] );
+		else
+			snprintf(exp,size,"PWD-AUTH");
+		break;
+	case MIFARE_ULEV1_FASTREAD:{
+		if ( cmdsize >=3 && cmd[2] <= 0xE6)
+			snprintf(exp,size,"READ RANGE (%d-%d)",cmd[1],cmd[2]); 
+		else
+			snprintf(exp,size,"?");
+		break;
+	}
+	case MIFARE_ULC_WRITE:{
+		if ( cmd[1] < 0x21 )
+			snprintf(exp,size,"WRITEBLOCK(%d)",cmd[1]); 
+		else
+			snprintf(exp,size,"?");
+		break;
+	}
+	case MIFARE_ULEV1_READ_CNT:{
+		if ( cmd[1] < 5 )
+			snprintf(exp,size,"READ CNT(%d)",cmd[1]);
+		else
+			snprintf(exp,size,"?");
+		break;
+	}
+	case MIFARE_ULEV1_INCR_CNT:{
+		if ( cmd[1] < 5 )
+			snprintf(exp,size,"INCR(%d)",cmd[1]);
+		else
+			snprintf(exp,size,"?");
+		break;
+	}
+	case MIFARE_ULEV1_READSIG:		snprintf(exp,size,"READ_SIG"); break;
+	case MIFARE_ULEV1_CHECKTEAR:	snprintf(exp,size,"CHK_TEARING(%d)",cmd[1]); break;
+	case MIFARE_ULEV1_VCSL:		snprintf(exp,size,"VCSL"); break;
 	default:						snprintf(exp,size,"?"); break;
 	}
 	return;
@@ -144,7 +193,6 @@ void annotateIso15693(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize)
 
 void annotateTopaz(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize)
 {
-
 	switch(cmd[0]) {
 		case TOPAZ_REQA						:snprintf(exp, size, "REQA");break;
 		case TOPAZ_WUPA						:snprintf(exp, size, "WUPA");break;
@@ -153,6 +201,10 @@ void annotateTopaz(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize)
 		case TOPAZ_READ						:snprintf(exp, size, "READ");break;
 		case TOPAZ_WRITE_E					:snprintf(exp, size, "WRITE-E");break;
 		case TOPAZ_WRITE_NE					:snprintf(exp, size, "WRITE-NE");break;
+		case TOPAZ_RSEG						:snprintf(exp, size, "RSEG");break;
+		case TOPAZ_READ8					:snprintf(exp, size, "READ8");break;
+		case TOPAZ_WRITE_E8					:snprintf(exp, size, "WRITE-E8");break;
+		case TOPAZ_WRITE_NE8				:snprintf(exp, size, "WRITE-NE8");break;
 		default:                            snprintf(exp,size,"?"); break;
 	}
 }
@@ -318,7 +370,7 @@ bool next_record_is_response(uint16_t tracepos, uint8_t *trace)
 bool merge_topaz_reader_frames(uint32_t timestamp, uint32_t *duration, uint16_t *tracepos, uint16_t traceLen, uint8_t *trace, uint8_t *frame, uint8_t *topaz_reader_command, uint16_t *data_len)
 {
 
-#define MAX_TOPAZ_READER_CMD_LEN	9
+#define MAX_TOPAZ_READER_CMD_LEN	16
 
 	uint32_t last_timestamp = timestamp + *duration;
 
@@ -354,7 +406,7 @@ bool merge_topaz_reader_frames(uint32_t timestamp, uint32_t *duration, uint16_t
 }
 
 
-uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, uint8_t protocol, bool showWaitCycles)
+uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, uint8_t protocol, bool showWaitCycles, bool markCRCBytes)
 {
 	bool isResponse;
 	uint16_t data_len, parity_len;
@@ -434,20 +486,24 @@ uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, ui
 			oddparity ^= (((frame[j] & 0xFF) >> k) & 0x01);
 		}
 		uint8_t parityBits = parityBytes[j>>3];
-		if (isResponse && (oddparity != ((parityBits >> (7-(j&0x0007))) & 0x01))) {
-			snprintf(line[j/16]+(( j % 16) * 4), 110, " %02x!", frame[j]);
+		if (protocol != ISO_14443B && (isResponse || protocol == ISO_14443A) && (oddparity != ((parityBits >> (7-(j&0x0007))) & 0x01))) {
+			snprintf(line[j/16]+(( j % 16) * 4),110, "%02x! ", frame[j]);
 		} else {
 			snprintf(line[j/16]+(( j % 16) * 4), 110, " %02x ", frame[j]);
 		}
 
 	}
-	if(crcStatus == 0 || crcStatus == 1)
-	{//CRC-command
-		char *pos1 = line[(data_len-2)/16]+(((data_len-2) % 16) * 4);
-		(*pos1) = '[';
-		char *pos2 = line[(data_len)/16]+(((data_len) % 16) * 4);
-		sprintf(pos2, "%c", ']');
+
+	if (markCRCBytes) {
+		if(crcStatus == 0 || crcStatus == 1)
+		{//CRC-command
+			char *pos1 = line[(data_len-2)/16]+(((data_len-2) % 16) * 4);
+			(*pos1) = '[';
+			char *pos2 = line[(data_len)/16]+(((data_len) % 16) * 4);
+			sprintf(pos2, "%c", ']');
+		}
 	}
+
 	if(data_len == 0)
 	{
 		if(data_len == 0){
@@ -474,7 +530,7 @@ uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, ui
 	int num_lines = MIN((data_len - 1)/16 + 1, 16);
 	for (int j = 0; j < num_lines ; j++) {
 		if (j == 0) {
-			PrintAndLog(" %9d | %9d | %s |%-64s | %s| %s",
+			PrintAndLog(" %10d | %10d | %s |%-64s | %s| %s",
 				(timestamp - first_timestamp),
 				(EndOfTransmissionTimestamp - first_timestamp),
 				(isResponse ? "Tag" : "Rdr"),
@@ -482,7 +538,7 @@ uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, ui
 				(j == num_lines-1) ? crc : "    ",
 				(j == num_lines-1) ? explanation : "");
 		} else {
-			PrintAndLog("           |           |     |%-64s | %s| %s",
+			PrintAndLog("            |            |     |%-64s | %s| %s",
 				line[j],
 				(j == num_lines-1) ? crc : "    ",
 				(j == num_lines-1) ? explanation : "");
@@ -507,22 +563,26 @@ uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, ui
 int CmdHFList(const char *Cmd)
 {
 	bool showWaitCycles = false;
+	bool markCRCBytes = false;
 	char type[40] = {0};
 	int tlen = param_getstr(Cmd,0,type);
-	char param = param_getchar(Cmd, 1);
+	char param1 = param_getchar(Cmd, 1);
+	char param2 = param_getchar(Cmd, 2);
 	bool errors = false;
 	uint8_t protocol = 0;
 	//Validate params
-	if(tlen == 0)
-	{
+
+	if(tlen == 0) {
 		errors = true;
 	}
-	if(param == 'h' || (param !=0 && param != 'f'))
-	{
+
+	if(param1 == 'h'
+			|| (param1 != 0 && param1 != 'f' && param1 != 'c')
+			|| (param2 != 0 && param2 != 'f' && param2 != 'c')) {
 		errors = true;
 	}
-	if(!errors)
-	{
+
+	if(!errors) {
 		if(strcmp(type, "iclass") == 0)	{
 			protocol = ICLASS;
 		} else if(strcmp(type, "14a") == 0) {
@@ -540,8 +600,9 @@ int CmdHFList(const char *Cmd)
 
 	if (errors) {
 		PrintAndLog("List protocol data in trace buffer.");
-		PrintAndLog("Usage:  hf list <protocol> [f]");
+		PrintAndLog("Usage:  hf list <protocol> [f][c]");
 		PrintAndLog("    f      - show frame delay times as well");
+		PrintAndLog("    c      - mark CRC bytes");
 		PrintAndLog("Supported <protocol> values:");
 		PrintAndLog("    raw    - just show raw data without annotations");
 		PrintAndLog("    14a    - interpret data as iso14443a communications");
@@ -555,10 +616,13 @@ int CmdHFList(const char *Cmd)
 	}
 
 
-	if (param == 'f') {
+	if (param1 == 'f' || param2 == 'f') {
 		showWaitCycles = true;
 	}
 
+	if (param1 == 'c' || param2 == 'c') {
+		markCRCBytes = true;
+	}
 
 	uint8_t *trace;
 	uint16_t tracepos = 0;
@@ -587,33 +651,70 @@ int CmdHFList(const char *Cmd)
 	PrintAndLog("iso14443a - All times are in carrier periods (1/13.56Mhz)");
 	PrintAndLog("iClass    - Timings are not as accurate");
 	PrintAndLog("");
-	PrintAndLog("     Start |       End | Src | Data (! denotes parity error)                                   | CRC | Annotation         |");
-	PrintAndLog("-----------|-----------|-----|-----------------------------------------------------------------|-----|--------------------|");
+	PrintAndLog("      Start |        End | Src | Data (! denotes parity error)                                   | CRC | Annotation         |");
+	PrintAndLog("------------|------------|-----|-----------------------------------------------------------------|-----|--------------------|");
 
 	while(tracepos < traceLen)
 	{
-		tracepos = printTraceLine(tracepos, traceLen, trace, protocol, showWaitCycles);
+		tracepos = printTraceLine(tracepos, traceLen, trace, protocol, showWaitCycles, markCRCBytes);
 	}
 
 	free(trace);
 	return 0;
 }
 
+int CmdHFSearch(const char *Cmd){
+	int ans = 0;
+	PrintAndLog("");
+	ans = CmdHF14AReader("s");
+	if (ans > 0) {
+		PrintAndLog("\nValid ISO14443A Tag Found - Quiting Search\n");
+		return ans;
+	}
+	ans = HFiClassReader("", false, false);
+	if (ans) {
+		PrintAndLog("\nValid iClass Tag (or PicoPass Tag) Found - Quiting Search\n");
+		return ans;
+	}
+	ans = HF14BInfo(false);
+	if (ans) {
+		PrintAndLog("\nValid ISO14443B Tag Found - Quiting Search\n");
+		return ans;
+	}
+	ans = HF15Reader("", false);
+	if (ans) {
+		PrintAndLog("\nValid ISO15693 Tag Found - Quiting Search\n");
+		return ans;
+	}
+	PrintAndLog("\nno known/supported 13.56 MHz tags found\n");
+	return 0;
+}
+
+int CmdHFSnoop(const char *Cmd)
+{
+	char * pEnd;
+	UsbCommand c = {CMD_HF_SNIFFER, {strtol(Cmd, &pEnd,0),strtol(pEnd, &pEnd,0),0}};
+	SendCommand(&c);
+	return 0;
+}
 
 static command_t CommandTable[] = 
 {
-  {"help",        CmdHelp,          1, "This help"},
-  {"14a",         CmdHF14A,         1, "{ ISO14443A RFIDs... }"},
-  {"14b",         CmdHF14B,         1, "{ ISO14443B RFIDs... }"},
-  {"15",          CmdHF15,          1, "{ ISO15693 RFIDs... }"},
-  {"epa",         CmdHFEPA,         1, "{ German Identification Card... }"},
-  {"legic",       CmdHFLegic,       0, "{ LEGIC RFIDs... }"},
-  {"iclass",      CmdHFiClass,      1, "{ ICLASS RFIDs... }"},
-  {"mf",      		CmdHFMF,		1, "{ MIFARE RFIDs... }"},
-  {"mfu",			CmdHFMFUltra,		1, "{ MIFARE Ultralight RFIDs... }"},
-  {"tune",        CmdHFTune,        0, "Continuously measure HF antenna tuning"},
-  {"list",       CmdHFList,         1, "List protocol data in trace buffer"},
-	{NULL, NULL, 0, NULL}
+	{"help",	CmdHelp,		1, "This help"},
+	{"14a",		CmdHF14A,		1, "{ ISO14443A RFIDs... }"},
+	{"14b",		CmdHF14B,		1, "{ ISO14443B RFIDs... }"},
+	{"15",		CmdHF15,		1, "{ ISO15693 RFIDs... }"},
+	{"epa",		CmdHFEPA,		1, "{ German Identification Card... }"},
+	{"legic",	CmdHFLegic,		0, "{ LEGIC RFIDs... }"},
+	{"iclass",	CmdHFiClass,	1, "{ ICLASS RFIDs... }"},
+	{"mf",		CmdHFMF,		1, "{ MIFARE RFIDs... }"},
+	{"mfu",		CmdHFMFUltra,	1, "{ MIFARE Ultralight RFIDs... }"},
+	{"topaz",	CmdHFTopaz,		1, "{ TOPAZ (NFC Type 1) RFIDs... }"},
+	{"tune",	CmdHFTune,		0, "Continuously measure HF antenna tuning"},
+	{"list",	CmdHFList,		1, "List protocol data in trace buffer"},
+	{"search",	CmdHFSearch,	1, "Search for known HF tags [preliminary]"},
+	{"snoop",   CmdHFSnoop,     0, "<samples to skip (10000)> <triggers to skip (1)> Generic HF Snoop"},
+	{NULL,		NULL,			0, NULL}
 };
 
 int CmdHF(const char *Cmd)