X-Git-Url: http://cvs.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/a88c28271c9208b996ae86d3468a4fdbd77c791d..160dba86970b71e23770929cb2b15b2454a1496f:/armsrc/mifarecmd.c

diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c
index 14d2b68a..8f141d65 100644
--- a/armsrc/mifarecmd.c
+++ b/armsrc/mifarecmd.c
@@ -16,6 +16,7 @@
 #include "mifarecmd.h"
 #include "apps.h"
 #include "util.h"
+#include "parity.h"
 #include "crc.h"
 
 // the block number for the ISO14443-4 PCB
@@ -44,10 +45,10 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
 	struct Crypto1State *pcs;
 	pcs = &mpcs;
 
-	// clear trace
-	clear_trace();
 	iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
 
+	clear_trace();
+
 	LED_A_ON();
 	LED_B_OFF();
 	LED_C_OFF();
@@ -95,9 +96,11 @@ void MifareUC_Auth(uint8_t arg0, uint8_t *keybytes){
 	bool turnOffField = (arg0 == 1);
 
 	LED_A_ON(); LED_B_OFF(); LED_C_OFF();
-	clear_trace();
+
 	iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
 
+	clear_trace();
+
 	if(!iso14443a_select_card(NULL, NULL, NULL)) {
 		if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card");
 		OnError(0);
@@ -129,9 +132,10 @@ void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain)
 
 	LEDsoff();
 	LED_A_ON();
-	clear_trace();
 	iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
 
+	clear_trace();
+
 	int len = iso14443a_select_card(NULL, NULL, NULL);
 	if(!len) {
 		if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card (RC:%02X)",len);
@@ -199,11 +203,10 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
 	struct Crypto1State *pcs;
 	pcs = &mpcs;
 
-	// clear trace
-	clear_trace();
-
 	iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
 
+	clear_trace();
+
 	LED_A_ON();
 	LED_B_OFF();
 	LED_C_OFF();
@@ -252,6 +255,10 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
 // datain = KEY bytes
 void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain)
 {
+	LEDsoff();
+	LED_A_ON();
+	iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
+
 	// free eventually allocated BigBuf memory
 	BigBuf_free();
 	clear_trace();
@@ -269,10 +276,6 @@ void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain)
 		return;
 	}
 
-	LEDsoff();
-	LED_A_ON();
-	iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
-
 	int len = iso14443a_select_card(NULL, NULL, NULL);
 	if (!len) {
 		if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card (RC:%d)",len);
@@ -366,11 +369,10 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
 	struct Crypto1State *pcs;
 	pcs = &mpcs;
 
-	// clear trace
-	clear_trace();
-
 	iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
 
+	clear_trace();
+
 	LED_A_ON();
 	LED_B_OFF();
 	LED_C_OFF();
@@ -472,9 +474,10 @@ void MifareUWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain)
 	
 	LEDsoff();
 	LED_A_ON();
-	clear_trace();
 	iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
 
+	clear_trace();
+
 	if(!iso14443a_select_card(NULL, NULL, NULL)) {
 		if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
 		OnError(0);
@@ -530,9 +533,10 @@ void MifareUSetPwd(uint8_t arg0, uint8_t *datain){
 	memcpy(pwd, datain, 16);
 	
 	LED_A_ON(); LED_B_OFF(); LED_C_OFF();
-	clear_trace();
 	iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
 
+	clear_trace();
+
 	if(!iso14443a_select_card(NULL, NULL, NULL)) {
 		if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
 		OnError(0);
@@ -592,9 +596,9 @@ void MifareUSetPwd(uint8_t arg0, uint8_t *datain){
 
 // Return 1 if the nonce is invalid else return 0
 int valid_nonce(uint32_t Nt, uint32_t NtEnc, uint32_t Ks1, uint8_t *parity) {
-	return ((oddparity((Nt >> 24) & 0xFF) == ((parity[0]) ^ oddparity((NtEnc >> 24) & 0xFF) ^ BIT(Ks1,16))) & \
-	(oddparity((Nt >> 16) & 0xFF) == ((parity[1]) ^ oddparity((NtEnc >> 16) & 0xFF) ^ BIT(Ks1,8))) & \
-	(oddparity((Nt >> 8) & 0xFF) == ((parity[2]) ^ oddparity((NtEnc >> 8) & 0xFF) ^ BIT(Ks1,0)))) ? 1 : 0;
+	return ((oddparity8((Nt >> 24) & 0xFF) == ((parity[0]) ^ oddparity8((NtEnc >> 24) & 0xFF) ^ BIT(Ks1,16))) & \
+	(oddparity8((Nt >> 16) & 0xFF) == ((parity[1]) ^ oddparity8((NtEnc >> 16) & 0xFF) ^ BIT(Ks1,8))) & \
+	(oddparity8((Nt >> 8) & 0xFF) == ((parity[2]) ^ oddparity8((NtEnc >> 8) & 0xFF) ^ BIT(Ks1,0)))) ? 1 : 0;
 }
 
 
@@ -632,18 +636,16 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
 	uint32_t auth1_time, auth2_time;
 	static uint16_t delta_time;
 
-	// free eventually allocated BigBuf memory
-	BigBuf_free();
-	// clear trace
-	clear_trace();
-	set_tracing(false);
-	
-	iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
-
 	LED_A_ON();
 	LED_C_OFF();
+	iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
 
+	// free eventually allocated BigBuf memory
+	BigBuf_free();
 
+	if (calibrate) clear_trace();
+	set_tracing(true);
+	
 	// statistics on nonce distance
 	int16_t isOK = 0;
 	#define NESTED_MAX_TRIES 12
@@ -769,7 +771,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
 			
 			// Parity validity check
 			for (j = 0; j < 4; j++) {
-				par_array[j] = (oddparity(receivedAnswer[j]) != ((par[0] >> (7-j)) & 0x01));
+				par_array[j] = (oddparity8(receivedAnswer[j]) != ((par[0] >> (7-j)) & 0x01));
 			}
 			
 			ncount = 0;
@@ -819,18 +821,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;
 	
@@ -847,15 +849,13 @@ void MifareChkKeys(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
 	int OLD_MF_DBGLEVEL = MF_DBGLEVEL;	
 	MF_DBGLEVEL = MF_DBG_NONE;
 	
-	// clear trace
-	clear_trace();
-	set_tracing(TRUE);
-
-	iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
-
 	LED_A_ON();
 	LED_B_OFF();
 	LED_C_OFF();
+	iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
+
+	if (clearTrace) clear_trace();
+	set_tracing(TRUE);
 
 	for (i = 0; i < keyCount; i++) {
 		if(mifare_classic_halt(pcs, cuid)) {
@@ -902,16 +902,23 @@ void MifareSetDbgLvl(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
 //-----------------------------------------------------------------------------
 // Work with emulator memory
 // 
+// Note: we call FpgaDownloadAndGo(FPGA_BITSTREAM_HF) here although FPGA is not
+// involved in dealing with emulator memory. But if it is called later, it might
+// destroy the Emulator Memory.
 //-----------------------------------------------------------------------------
+
 void MifareEMemClr(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){
+	FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
 	emlClearMem();
 }
 
 void MifareEMemSet(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){
+	FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
 	emlSetMem(datain, arg0, arg1); // data, block num, blocks count
 }
 
 void MifareEMemGet(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){
+	FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
 	byte_t buf[USB_CMD_DATA_SIZE];
 	emlGetMem(buf, arg0, arg1); // data, block num, blocks count (max 4)
 
@@ -938,15 +945,13 @@ void MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
 	byte_t dataoutbuf2[16];
 	uint8_t uid[10];
 
-	// clear trace
-	clear_trace();
-	set_tracing(false);
-	
-	iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
-
 	LED_A_ON();
 	LED_B_OFF();
 	LED_C_OFF();
+	iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
+	
+	clear_trace();
+	set_tracing(false);
 	
 	bool isOK = true;
 
@@ -1040,10 +1045,10 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
 		LED_A_ON();
 		LED_B_OFF();
 		LED_C_OFF();
+		iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
 	
 		clear_trace();
 		set_tracing(TRUE);
-		iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
 	}
 
 	while (true) {
@@ -1139,6 +1144,7 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
 	// bit 2 - need HALT after sequence
 	// bit 3 - need init FPGA and field before sequence
 	// bit 4 - need reset FPGA and LED
+	// bit 5 - need to set datain instead of issuing USB reply (called via ARM for StandAloneMode14a)
 	uint8_t workFlags = arg0;
 	uint8_t blockNo = arg2;
 	
@@ -1158,10 +1164,10 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
 		LED_A_ON();
 		LED_B_OFF();
 		LED_C_OFF();
-	
+		iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
+
 		clear_trace();
 		set_tracing(TRUE);
-		iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
 	}
 
 	while (true) {
@@ -1198,7 +1204,12 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
 	}
 	
 	LED_B_ON();
-	cmd_send(CMD_ACK,isOK,0,0,data,18);
+	if (workFlags & 0x20) {
+		if (isOK)
+			memcpy(datain, data, 18);
+	}
+	else
+		cmd_send(CMD_ACK,isOK,0,0,data,18);
 	LED_B_OFF();
 
 	if ((workFlags & 0x10) || (!isOK)) {
@@ -1236,7 +1247,7 @@ void MifareCIdent(){
 	cmd_send(CMD_ACK,isOK,0,0,0,0);
 }
 
-			//
+//
 // DESFIRE
 //
 
@@ -1246,8 +1257,8 @@ void Mifare_DES_Auth1(uint8_t arg0, uint8_t *datain){
 	uint8_t uid[10] = {0x00};
 	uint32_t cuid;
     
-	clear_trace();
 	iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
+	clear_trace();
 
 	int len = iso14443a_select_card(uid, NULL, &cuid);
 	if(!len) {