From 5330f5329f68fa6a95658ebd946d5eefc74e10c4 Mon Sep 17 00:00:00 2001
From: pwpiwi <pwpiwi@users.noreply.github.com>
Date: Thu, 2 Jul 2015 08:49:34 +0200
Subject: [PATCH] - fix: trace of hf mf mifare had always been cleared by
 mfCheckKeys() in nonce2key() - fix: parity was not checked for reader
 commands in hf list 14a - add: enable tracing for hf mf nested

---
 armsrc/BigBuf.h              | 14 +++++++-------
 armsrc/apps.h                |  2 +-
 armsrc/mifarecmd.c           | 14 +++++++-------
 client/cmdhf.c               |  2 +-
 client/cmdhfmf.c             | 22 ++++++----------------
 client/mifarehost.c          |  6 +++---
 client/mifarehost.h          |  2 +-
 client/nonce2key/nonce2key.c |  2 +-
 8 files changed, 27 insertions(+), 37 deletions(-)

diff --git a/armsrc/BigBuf.h b/armsrc/BigBuf.h
index b44a1263..0e2f1744 100644
--- a/armsrc/BigBuf.h
+++ b/armsrc/BigBuf.h
@@ -24,15 +24,15 @@
 extern uint8_t *BigBuf_get_addr(void);
 extern uint8_t *BigBuf_get_EM_addr(void);
 extern uint16_t BigBuf_max_traceLen(void);
-void BigBuf_Clear(void);
+extern void BigBuf_Clear(void);
 extern uint8_t *BigBuf_malloc(uint16_t);
 extern void BigBuf_free(void);
 extern void BigBuf_free_keep_EM(void);
 
-uint16_t BigBuf_get_traceLen(void);
-void clear_trace();
-void set_tracing(bool enable);
-bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag);
-int LogTraceHitag(const uint8_t * btBytes, int iBits, int iSamples, uint32_t dwParity, int bReader);
-uint8_t emlSet(uint8_t *data, uint32_t offset, uint32_t length);
+extern uint16_t BigBuf_get_traceLen(void);
+extern void clear_trace();
+extern void set_tracing(bool enable);
+extern bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag);
+extern int LogTraceHitag(const uint8_t * btBytes, int iBits, int iSamples, uint32_t dwParity, int bReader);
+extern uint8_t emlSet(uint8_t *data, uint32_t offset, uint32_t length);
 #endif /* __BIGBUF_H */
diff --git a/armsrc/apps.h b/armsrc/apps.h
index bb094b33..42efd118 100644
--- a/armsrc/apps.h
+++ b/armsrc/apps.h
@@ -121,7 +121,7 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
 //void MifareUWriteBlockCompat(uint8_t arg0,uint8_t *datain);
 void MifareUWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain);
 void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
-void MifareChkKeys(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain);
+void MifareChkKeys(uint16_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain);
 void Mifare1ksim(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain);
 void MifareSetDbgLvl(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
 void MifareEMemClr(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c
index c2d85abb..fd6fde63 100644
--- a/armsrc/mifarecmd.c
+++ b/armsrc/mifarecmd.c
@@ -642,8 +642,8 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
 	// free eventually allocated BigBuf memory
 	BigBuf_free();
 
-	clear_trace();
-	set_tracing(false);
+	if (calibrate) clear_trace();
+	set_tracing(true);
 	
 	// statistics on nonce distance
 	int16_t isOK = 0;
@@ -820,18 +820,18 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
 
 	FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
 	LEDsoff();
-	set_tracing(TRUE);
 }
 
 //-----------------------------------------------------------------------------
 // MIFARE check keys. key count up to 85. 
 // 
 //-----------------------------------------------------------------------------
-void MifareChkKeys(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
+void MifareChkKeys(uint16_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
 {
   // params
-	uint8_t blockNo = arg0;
-	uint8_t keyType = arg1;
+	uint8_t blockNo = arg0 & 0xff;
+	uint8_t keyType = (arg0 >> 8) & 0xff;
+	bool clearTrace = arg1;
 	uint8_t keyCount = arg2;
 	uint64_t ui64Key = 0;
 	
@@ -853,7 +853,7 @@ void MifareChkKeys(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
 	LED_C_OFF();
 	iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
 
-	clear_trace();
+	if (clearTrace) clear_trace();
 	set_tracing(TRUE);
 
 	for (i = 0; i < keyCount; i++) {
diff --git a/client/cmdhf.c b/client/cmdhf.c
index 4c5db589..f8daff7e 100644
--- a/client/cmdhf.c
+++ b/client/cmdhf.c
@@ -378,7 +378,7 @@ 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 (protocol != ISO_14443B && isResponse && (oddparity != ((parityBits >> (7-(j&0x0007))) & 0x01))) {
+		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 {
diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c
index 5ef5273a..16612cba 100644
--- a/client/cmdhfmf.c
+++ b/client/cmdhfmf.c
@@ -18,7 +18,6 @@ int CmdHF14AMifare(const char *Cmd)
 	uint32_t nt = 0, nr = 0;
 	uint64_t par_list = 0, ks_list = 0, r_key = 0;
 	int16_t isOK = 0;
-	uint8_t keyBlock[8] = {0};
 
 	UsbCommand c = {CMD_READER_MIFARE, {true, 0, 0}};
 
@@ -74,22 +73,13 @@ start:
 	if (nonce2key(uid, nt, nr, par_list, ks_list, &r_key)) {
 		isOK = 2;
 		PrintAndLog("Key not found (lfsr_common_prefix list is null). Nt=%08x", nt);	
-	} else {
-		printf("------------------------------------------------------------------\n");
-		PrintAndLog("Key found:%012"llx" \n", r_key);
-
-		num_to_bytes(r_key, 6, keyBlock);
-		isOK = mfCheckKeys(0, 0, 1, keyBlock, &r_key);
-	}
-	
-	if (!isOK) 
-		PrintAndLog("Found valid key:%012"llx, r_key);
-	else
-	{
-		if (isOK != 2) PrintAndLog("Found invalid key. ");	
 		PrintAndLog("Failing is expected to happen in 25%% of all cases. Trying again with a different reader nonce...");
 		c.arg[0] = false;
 		goto start;
+	} else {
+		isOK = 0;
+		printf("------------------------------------------------------------------\n");
+		PrintAndLog("Found valid key:%012"llx" \n", r_key);
 	}
 	
 	PrintAndLog("");
@@ -689,7 +679,7 @@ int CmdHF14AMfNested(const char *Cmd)
 			for (j = 0; j < 2; j++) {
 				if (e_sector[i].foundKey[j]) continue;
 				
-				res = mfCheckKeys(FirstBlockOfSector(i), j, 6, keyBlock, &key64);
+				res = mfCheckKeys(FirstBlockOfSector(i), j, true, 6, keyBlock, &key64);
 				
 				if (!res) {
 					e_sector[i].Key[j] = key64;
@@ -973,7 +963,7 @@ int CmdHF14AMfChk(const char *Cmd)
 			uint32_t max_keys = keycnt>USB_CMD_DATA_SIZE/6?USB_CMD_DATA_SIZE/6:keycnt;
 			for (uint32_t c = 0; c < keycnt; c+=max_keys) {
 				uint32_t size = keycnt-c>max_keys?max_keys:keycnt-c;
-				res = mfCheckKeys(b, t, size, &keyBlock[6*c], &key64);
+				res = mfCheckKeys(b, t, true, size, &keyBlock[6*c], &key64);
 				if (res != 1) {
 					if (!res) {
 						PrintAndLog("Found valid key:[%012"llx"]",key64);
diff --git a/client/mifarehost.c b/client/mifarehost.c
index 95453ebf..eb145123 100644
--- a/client/mifarehost.c
+++ b/client/mifarehost.c
@@ -181,7 +181,7 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t * key, uint8_t trgBlockNo
 		crypto1_get_lfsr(statelists[0].head.slhead + i, &key64);
 		num_to_bytes(key64, 6, keyBlock);
 		key64 = 0;
-		if (!mfCheckKeys(statelists[0].blockNo, statelists[0].keyType, 1, keyBlock, &key64)) {
+		if (!mfCheckKeys(statelists[0].blockNo, statelists[0].keyType, false, 1, keyBlock, &key64)) {
 			num_to_bytes(key64, 6, resultKey);
 			break;
 		}
@@ -193,11 +193,11 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t * key, uint8_t trgBlockNo
 	return 0;
 }
 
-int mfCheckKeys (uint8_t blockNo, uint8_t keyType, uint8_t keycnt, uint8_t * keyBlock, uint64_t * key){
+int mfCheckKeys (uint8_t blockNo, uint8_t keyType, bool clear_trace, uint8_t keycnt, uint8_t * keyBlock, uint64_t * key){
 
 	*key = 0;
 
-	UsbCommand c = {CMD_MIFARE_CHKKEYS, {blockNo, keyType, keycnt}};
+	UsbCommand c = {CMD_MIFARE_CHKKEYS, {((blockNo & 0xff) | ((keyType&0xff)<<8)), clear_trace, keycnt}};
 	memcpy(c.d.asBytes, keyBlock, 6 * keycnt);
 	SendCommand(&c);
 
diff --git a/client/mifarehost.h b/client/mifarehost.h
index a11f11d5..f6ffab3f 100644
--- a/client/mifarehost.h
+++ b/client/mifarehost.h
@@ -50,7 +50,7 @@ typedef struct {
 extern char logHexFileName[FILE_PATH_SIZE];
 
 int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t * key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t * ResultKeys, bool calibrate);
-int mfCheckKeys (uint8_t blockNo, uint8_t keyType, uint8_t keycnt, uint8_t * keyBlock, uint64_t * key);
+int mfCheckKeys (uint8_t blockNo, uint8_t keyType, bool clear_trace, uint8_t keycnt, uint8_t * keyBlock, uint64_t * key);
 
 int mfEmlGetMem(uint8_t *data, int blockNum, int blocksCount);
 int mfEmlSetMem(uint8_t *data, int blockNum, int blocksCount);
diff --git a/client/nonce2key/nonce2key.c b/client/nonce2key/nonce2key.c
index 111f58cd..70d874fe 100644
--- a/client/nonce2key/nonce2key.c
+++ b/client/nonce2key/nonce2key.c
@@ -133,7 +133,7 @@ int nonce2key(uint32_t uid, uint32_t nt, uint32_t nr, uint64_t par_info, uint64_
 		key64 = *(last_keylist + i);
 		num_to_bytes(key64, 6, keyBlock);
 		key64 = 0;
-		if (!mfCheckKeys(0, 0, 1, keyBlock, &key64)) {
+		if (!mfCheckKeys(0, 0, false, 1, keyBlock, &key64)) {
 			*key = key64;
 			free(last_keylist);
 			last_keylist = NULL;
-- 
2.39.5