X-Git-Url: http://cvs.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/b725f2ca21d11709b5e61595bd88ae260fee4c7f..21d359f68fcaae74f383aaef49c15357389d4a9d:/armsrc/mifarecmd.c

diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c
index 0443c1f1..93eea212 100644
--- a/armsrc/mifarecmd.c
+++ b/armsrc/mifarecmd.c
@@ -4,7 +4,7 @@
 // Hagen Fritsch - June 2010
 // Midnitesnake - Dec 2013
 // Andy Davies  - Apr 2014
-// Iceman - May 2014
+// Iceman - May 2014,2015,2016
 //
 // This code is licensed to you under the terms of the GNU GPL, version 2 or,
 // at your option, any later version. See the LICENSE.txt file for the text of
@@ -44,6 +44,7 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
 	iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
 
 	clear_trace();
+	set_tracing(true);
 
 	LED_A_ON();
 	LED_B_OFF();
@@ -74,7 +75,6 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
 		break;
 	}
 	
-	//  ----------------------------- crypto1 destroy
 	crypto1_destroy(pcs);
 	
 	if (MF_DBGLEVEL >= 2)	DbpString("READ BLOCK FINISHED");
@@ -96,6 +96,7 @@ void MifareUC_Auth(uint8_t arg0, uint8_t *keybytes){
 	iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
 
 	clear_trace();
+	set_tracing(true);
 
 	if(!iso14443a_select_card(NULL, NULL, NULL, true, 0)) {
 		if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card");
@@ -131,6 +132,7 @@ void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain)
 	iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
 
 	clear_trace();
+	set_tracing(true);
 
 	int len = iso14443a_select_card(NULL, NULL, NULL, true, 0);
 	if(!len) {
@@ -202,7 +204,8 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
 	iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
 
 	clear_trace();
-
+	set_tracing(true);
+	
 	LED_A_ON();
 	LED_B_OFF();
 	LED_C_OFF();
@@ -231,18 +234,17 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
 		if (MF_DBGLEVEL >= 1)	Dbprintf("Halt error");
 	}
 
-	//  ----------------------------- crypto1 destroy
-	crypto1_destroy(pcs);
-	
 	if (MF_DBGLEVEL >= 2) DbpString("READ SECTOR FINISHED");
 
+	crypto1_destroy(pcs);
+
 	LED_B_ON();
 	cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,16*NumBlocksPerSector(sectorNo));
 	LED_B_OFF();
 
-	// Thats it...
 	FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
 	LEDsoff();
+	set_tracing(FALSE);
 }
 
 // arg0 = blockNo (start)
@@ -256,9 +258,10 @@ void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain)
 	iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
 
 	// free eventually allocated BigBuf memory
-	BigBuf_free();
+	BigBuf_free(); BigBuf_Clear_ext(false);
 	clear_trace();
-
+	set_tracing(true);
+	
 	// params
 	uint8_t blockNo = arg0;
 	uint16_t blocks = arg1;
@@ -340,6 +343,7 @@ void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain)
 	FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
 	LEDsoff();
 	BigBuf_free();
+	set_tracing(FALSE);
 }
 
 //-----------------------------------------------------------------------------
@@ -368,7 +372,8 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
 	iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
 
 	clear_trace();
-
+	set_tracing(true);
+	
 	LED_A_ON();
 	LED_B_OFF();
 	LED_C_OFF();
@@ -407,10 +412,9 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
 	cmd_send(CMD_ACK,isOK,0,0,0,0);
 	LED_B_OFF();
 
-
-	// Thats it...
 	FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
 	LEDsoff();
+	set_tracing(FALSE);
 }
 
 /* // Command not needed but left for future testing 
@@ -426,6 +430,7 @@ void MifareUWriteBlockCompat(uint8_t arg0, uint8_t *datain)
 	LED_A_ON(); LED_B_OFF(); LED_C_OFF();
 
 	clear_trace();
+	set_tracing(true);
 	iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
 
 	if(!iso14443a_select_card(uid, NULL, NULL, true, 0)) {
@@ -473,7 +478,8 @@ void MifareUWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain)
 	iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
 
 	clear_trace();
-
+	set_tracing(true);
+	
 	if(!iso14443a_select_card(NULL, NULL, NULL, true, 0)) {
 		if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
 		OnError(0);
@@ -519,6 +525,7 @@ void MifareUWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain)
 	cmd_send(CMD_ACK,1,0,0,0,0);
 	FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
 	LEDsoff();
+	set_tracing(FALSE);
 }
 
 void MifareUSetPwd(uint8_t arg0, uint8_t *datain){
@@ -532,7 +539,8 @@ void MifareUSetPwd(uint8_t arg0, uint8_t *datain){
 	iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
 
 	clear_trace();
-
+	set_tracing(true);
+	
 	if(!iso14443a_select_card(NULL, NULL, NULL, true, 0)) {
 		if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
 		OnError(0);
@@ -588,6 +596,7 @@ void MifareUSetPwd(uint8_t arg0, uint8_t *datain){
 	cmd_send(CMD_ACK,1,0,0,0,0);
 	FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
 	LEDsoff();
+	set_tracing(FALSE);
 }
 
 // Return 1 if the nonce is invalid else return 0
@@ -604,6 +613,9 @@ int valid_nonce(uint32_t Nt, uint32_t NtEnc, uint32_t Ks1, uint8_t *parity) {
 // Mifare Classic Cards" in Proceedings of the 22nd ACM SIGSAC Conference on 
 // Computer and Communications Security, 2015
 //-----------------------------------------------------------------------------
+#define AUTHENTICATION_TIMEOUT 848			// card times out 1ms after wrong authentication (according to NXP documentation)
+#define PRE_AUTHENTICATION_LEADTIME 400		// some (non standard) cards need a pause after select before they are ready for first authentication 
+
 void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, uint8_t *datain)
 {
 	uint64_t ui64Key = 0;
@@ -629,9 +641,6 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags,
 	bool slow = flags & 0x0002;
 	bool field_off = flags & 0x0004;
 	
-	#define AUTHENTICATION_TIMEOUT 848			// card times out 1ms after wrong authentication (according to NXP documentation)
-	#define PRE_AUTHENTICATION_LEADTIME 400		// some (non standard) cards need a pause after select before they are ready for first authentication 
-	
 	LED_A_ON();
 	LED_C_OFF();
 
@@ -707,10 +716,8 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags,
 			memcpy(buf+i+8, &nt_par_enc, 1);
 			i += 9;
 		}
-
 		// wait for the card to become ready again
-		while(GetCountSspClk() < timeout);
-	
+		while(GetCountSspClk() < timeout);	
 	}
 
 	LED_C_OFF();
@@ -726,6 +733,7 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags,
 	if (field_off) {
 		FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
 		LEDsoff();
+		set_tracing(FALSE);
 	}
 }
 
@@ -762,15 +770,15 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
 	uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00};
 
 	uint32_t auth1_time, auth2_time;
-	static uint16_t delta_time;
+	static uint16_t delta_time = 0;
 
 	LED_A_ON();
 	LED_C_OFF();
 	iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
 
 	// free eventually allocated BigBuf memory
-	BigBuf_free();
-
+	BigBuf_free(); BigBuf_Clear_ext(false);
+	
 	if (calibrate) clear_trace();
 	set_tracing(true);
 
@@ -813,12 +821,8 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
 				rtr--;
 				continue;
 			};
+			auth2_time = (delta_time) ? auth1_time + delta_time : 0;
 
-			if (delta_time) {
-				auth2_time = auth1_time + delta_time;
-			} else {
-				auth2_time = 0;
-			}
 			if(mifare_classic_authex(pcs, cuid, blockNo, keyType, ui64Key, AUTH_NESTED, &nt2, &auth2_time)) {
 				if (MF_DBGLEVEL >= 1)	Dbprintf("Nested: Auth2 error");
 				rtr--;
@@ -887,6 +891,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
 
 			// nested authentication
 			auth2_time = auth1_time + delta_time;
+
 			len = mifare_sendcmd_short(pcs, AUTH_NESTED, 0x60 + (targetKeyType & 0x01), targetBlockNo, receivedAnswer, par, &auth2_time);
 			if (len != 4) {
 				if (MF_DBGLEVEL >= 1)	Dbprintf("Nested: Auth2 error len=%d", len);
@@ -897,9 +902,13 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
 			if (MF_DBGLEVEL >= 3) Dbprintf("Nonce#%d: Testing nt1=%08x nt2enc=%08x nt2par=%02x", i+1, nt1, nt2, par[0]);
 			
 			// Parity validity check
-			for (j = 0; j < 4; j++) {
-				par_array[j] = (oddparity8(receivedAnswer[j]) != ((par[0] >> (7-j)) & 0x01));
-			}
+//			for (j = 0; j < 4; j++) {
+//				par_array[j] = (oddparity8(receivedAnswer[j]) != ((par[0] >> (7-j)) & 0x01));
+//			}
+			par_array[0] = (oddparity8(receivedAnswer[0]) != ((par[0] >> (7-0)) & 0x01));
+			par_array[1] = (oddparity8(receivedAnswer[1]) != ((par[0] >> (7-1)) & 0x01));
+			par_array[2] = (oddparity8(receivedAnswer[2]) != ((par[0] >> (7-2)) & 0x01));
+			par_array[3] = (oddparity8(receivedAnswer[3]) != ((par[0] >> (7-3)) & 0x01));
 			
 			ncount = 0;
 			nttest = prng_successor(nt1, dmin - 1);
@@ -930,10 +939,9 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
 
 	LED_C_OFF();
 	
-	//  ----------------------------- crypto1 destroy
 	crypto1_destroy(pcs);
 	
-	byte_t buf[4 + 4 * 4];
+	byte_t buf[4 + 4 * 4] = {0};
 	memcpy(buf, &cuid, 4);
 	memcpy(buf+4, &target_nt[0], 4);
 	memcpy(buf+8, &target_ks[0], 4);
@@ -955,16 +963,17 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
 // MIFARE check keys. key count up to 85. 
 // 
 //-----------------------------------------------------------------------------
-void MifareChkKeys(uint16_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
-{
-  // params
+void MifareChkKeys(uint16_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) {
 	uint8_t blockNo = arg0 & 0xff;
 	uint8_t keyType = (arg0 >> 8) & 0xff;
 	bool clearTrace = arg1;
 	uint8_t keyCount = arg2;
 	uint64_t ui64Key = 0;
 	
-	// variables
+	bool have_uid = FALSE;
+	uint8_t cascade_levels = 0;
+	uint32_t timeout = 0;
+	
 	int i;
 	byte_t isOK = 0;
 	uint8_t uid[10] = {0x00};
@@ -973,50 +982,72 @@ void MifareChkKeys(uint16_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
 	struct Crypto1State *pcs;
 	pcs = &mpcs;
 	
-	// clear debug level
+	// save old debuglevel, and tempory turn off dbg printing. speedissues.
 	int OLD_MF_DBGLEVEL = MF_DBGLEVEL;	
 	MF_DBGLEVEL = MF_DBG_NONE;
 	
+	LEDsoff();
 	LED_A_ON();
-	LED_B_OFF();
-	LED_C_OFF();
+	
 	iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
 
-	if (clearTrace) clear_trace();
+	if (clearTrace) 
+		clear_trace();
+	
 	set_tracing(TRUE);
+	
+	for (i = 0; i < keyCount; ++i) {
 
-	for (i = 0; i < keyCount; i++) {
-		if(mifare_classic_halt(pcs, cuid)) {
-			if (MF_DBGLEVEL >= 1)	Dbprintf("ChkKeys: Halt error");
-		}
-
-		if(!iso14443a_select_card(uid, NULL, &cuid, true, 0)) {
-			if (OLD_MF_DBGLEVEL >= 1)	Dbprintf("ChkKeys: Can't select card");
-			break;
-		};
+		//mifare_classic_halt(pcs, cuid);
 
+		// this part is from Piwi's faster nonce collecting part in Hardnested.
+		if (!have_uid) { // need a full select cycle to get the uid first
+			iso14a_card_select_t card_info;		
+			if(!iso14443a_select_card(uid, &card_info, &cuid, true, 0)) {
+				if (MF_DBGLEVEL >= 1)	Dbprintf("ChkKeys: Can't select card (ALL)");
+				break;
+			}
+			switch (card_info.uidlen) {
+				case 4 : cascade_levels = 1; break;
+				case 7 : cascade_levels = 2; break;
+				case 10: cascade_levels = 3; break;
+				default: break;
+			}
+			have_uid = TRUE;	
+		} else { // no need for anticollision. We can directly select the card
+			if(!iso14443a_select_card(uid, NULL, NULL, false, cascade_levels)) {
+				if (MF_DBGLEVEL >= 1)	Dbprintf("ChkKeys: Can't select card (UID)");
+				continue;
+			}
+		}
+	
 		ui64Key = bytes_to_num(datain + i * 6, 6);
-		if(mifare_classic_auth(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST)) {
-			continue;
-		};
 		
+		if (mifare_classic_auth(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST)) {
+
+			uint8_t dummy_answer = 0;
+			ReaderTransmit(&dummy_answer, 1, NULL);
+			timeout = GetCountSspClk() + AUTHENTICATION_TIMEOUT;
+			
+			// wait for the card to become ready again
+			while(GetCountSspClk() < timeout);
+			
+			continue;
+		}
 		isOK = 1;
 		break;
 	}
 	
-	//  ----------------------------- crypto1 destroy
-	crypto1_destroy(pcs);
-	
 	LED_B_ON();
-    cmd_send(CMD_ACK,isOK,0,0,datain + i * 6,6);
-	LED_B_OFF();
+    cmd_send(CMD_ACK, isOK, 0, 0, datain + i * 6, 6);
 
+	// restore debug level
+	MF_DBGLEVEL = OLD_MF_DBGLEVEL;	
+	
 	FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
 	LEDsoff();
 	set_tracing(FALSE);
-	
-	// restore debug level
-	MF_DBGLEVEL = OLD_MF_DBGLEVEL;	
+	crypto1_destroy(pcs);
 }
 
 //-----------------------------------------------------------------------------
@@ -1164,15 +1195,15 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain){
 	uint8_t workFlags = arg0;
 	uint8_t blockNo = arg1;
 	
-	Dbprintf("ICE :: CSetBlocks Flags %02x", workFlags);
-	
 	// variables
+	bool isOK = false; //assume we will get an error
+	uint8_t errormsg = 0x00;
 	uint8_t uid[10] = {0x00};
 	uint8_t data[18] = {0x00};
 	uint32_t cuid = 0;
 	
-	uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
-	uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
+	uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00};
+	uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE] = {0x00};
 
 	if (workFlags & MAGIC_INIT) {
 		LED_A_ON();
@@ -1182,65 +1213,83 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain){
 		set_tracing(TRUE);
 	}
 
-	// read UID and return to client
-	if (workFlags & MAGIC_UID) {
-		if(!iso14443a_select_card(uid, NULL, &cuid, true, 0)) {
-			if (MF_DBGLEVEL >= MF_DBG_ERROR)	Dbprintf("Can't select card");
-			OnErrorMagic(MAGIC_UID);
+	//loop doesn't loop just breaks out if error
+	while (true) {
+		// read UID and return to client with write
+		if (workFlags & MAGIC_UID) {
+			if(!iso14443a_select_card(uid, NULL, &cuid, true, 0)) {
+				if (MF_DBGLEVEL >= MF_DBG_ERROR)	Dbprintf("Can't select card");
+				errormsg = MAGIC_UID;
+				// break;
+			}
+			
+			if ( mifare_classic_halt_ex(NULL) ) break;
 		}
-	}
 	
-	// wipe tag, fill it with zeros
-	if (workFlags & MAGIC_WIPE){
-		ReaderTransmitBitsPar(wupC1,7,0, NULL);
-		if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
-			if (MF_DBGLEVEL >= MF_DBG_ERROR)	Dbprintf("wupC1 error");
-			OnErrorMagic(MAGIC_WIPE);
-		}
+		// wipe tag, fill it with zeros
+		if (workFlags & MAGIC_WIPE){
+			ReaderTransmitBitsPar(wupC1, 7, NULL, NULL);
+			if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
+				if (MF_DBGLEVEL >= MF_DBG_ERROR)	Dbprintf("wupC1 error");
+				errormsg = MAGIC_WIPE;
+				break;
+			}
 
-		ReaderTransmit(wipeC, sizeof(wipeC), NULL);
-		if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
-			if (MF_DBGLEVEL >= MF_DBG_ERROR)	Dbprintf("wipeC error");
-			OnErrorMagic(MAGIC_WIPE);
-		}
-	}	
+			ReaderTransmit(wipeC, sizeof(wipeC), NULL);
+			if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
+				if (MF_DBGLEVEL >= MF_DBG_ERROR)	Dbprintf("wipeC error");
+				errormsg = MAGIC_WIPE;
+				break;
+			}
 
-	// write block
-	if (workFlags & MAGIC_WUPC) {
-		ReaderTransmitBitsPar(wupC1,7,0, NULL);
-		if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
-			if (MF_DBGLEVEL >= MF_DBG_ERROR)	Dbprintf("wupC1 error");
-			OnErrorMagic(MAGIC_WUPC);
-		}
+			if ( mifare_classic_halt_ex(NULL) ) break;
+		}	
+
+		// write block
+		if (workFlags & MAGIC_WUPC) {
+			ReaderTransmitBitsPar(wupC1, 7, NULL, NULL);
+			if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
+				if (MF_DBGLEVEL >= MF_DBG_ERROR)	Dbprintf("wupC1 error");
+				errormsg = MAGIC_WUPC;
+				break;
+			}
 
-		ReaderTransmit(wupC2, sizeof(wupC2), NULL);
-		if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
-			if (MF_DBGLEVEL >= MF_DBG_ERROR)	Dbprintf("wupC2 error");
-			OnErrorMagic(MAGIC_WUPC);
+			ReaderTransmit(wupC2, sizeof(wupC2), NULL);
+			if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
+				if (MF_DBGLEVEL >= MF_DBG_ERROR)	Dbprintf("wupC2 error");
+				errormsg = MAGIC_WUPC;
+				break;
+			}
 		}
-	}
 
-	if ((mifare_sendcmd_short(NULL, 0, ISO14443A_CMD_WRITEBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 1) || (receivedAnswer[0] != 0x0a)) {
-		if (MF_DBGLEVEL >= MF_DBG_ERROR)	Dbprintf("write block send command error");
-		OnErrorMagic(4);
-	}
-	
-	memcpy(data, datain, 16);
-	AppendCrc14443a(data, 16);
+		if ((mifare_sendcmd_short(NULL, 0, ISO14443A_CMD_WRITEBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 1) || (receivedAnswer[0] != 0x0a)) {
+			if (MF_DBGLEVEL >= MF_DBG_ERROR)	Dbprintf("write block send command error");
+			errormsg = 4;
+			break;
+		}
 	
-	ReaderTransmit(data, sizeof(data), NULL);
-	if ((ReaderReceive(receivedAnswer, receivedAnswerPar) != 1) || (receivedAnswer[0] != 0x0a)) {
-		if (MF_DBGLEVEL >= MF_DBG_ERROR)	Dbprintf("write block send data error");
-		OnErrorMagic(0);
-	}	
+		memcpy(data, datain, 16);
+		AppendCrc14443a(data, 16);
 	
-	if (workFlags & MAGIC_OFF) 
-		mifare_classic_halt_ex(NULL);
+		ReaderTransmit(data, sizeof(data), NULL);
+		if ((ReaderReceive(receivedAnswer, receivedAnswerPar) != 1) || (receivedAnswer[0] != 0x0a)) {
+			if (MF_DBGLEVEL >= MF_DBG_ERROR)	Dbprintf("write block send data error");
+			errormsg = 0;
+			break;
+		}	
 	
-	LED_B_ON();
-	// check if uid is cuid?
-	cmd_send(CMD_ACK,1,0,0,uid,sizeof(uid));
-	LED_B_OFF();
+		if (workFlags & MAGIC_OFF) 
+			if ( mifare_classic_halt_ex(NULL) ) break;
+		
+		isOK = true;
+		break;
+
+	} // end while	
+
+	if (isOK )
+		cmd_send(CMD_ACK,1,0,0,uid,sizeof(uid));
+	else
+		OnErrorMagic(errormsg);
 
 	if (workFlags & MAGIC_OFF)
 		OnSuccessMagic();
@@ -1250,11 +1299,13 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain){
     
 	uint8_t workFlags = arg0;
 	uint8_t blockNo = arg1;
-
+	uint8_t errormsg = 0x00;
+	bool isOK = false; //assume we will get an error
+	
 	// variables
 	uint8_t data[MAX_MIFARE_FRAME_SIZE];
-	uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
-	uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
+	uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00};
+	uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE] = {0x00};
 	
 	memset(data, 0x00, sizeof(data));
 	
@@ -1266,42 +1317,51 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain){
 		set_tracing(TRUE);
 	}
 
-	if (workFlags & MAGIC_WUPC) {
-		ReaderTransmitBitsPar(wupC1,7,0, NULL);
-		if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
-			if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("wupC1 error");
-			OnErrorMagic(MAGIC_WUPC);
+	//loop doesn't loop just breaks out if error or done
+	while (true) {
+		if (workFlags & MAGIC_WUPC) {
+			ReaderTransmitBitsPar(wupC1, 7, NULL, NULL);
+			if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
+				if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("wupC1 error");
+				errormsg = MAGIC_WUPC;
+				break;
+			}
+
+			ReaderTransmit(wupC2, sizeof(wupC2), NULL);
+			if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
+				if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("wupC2 error");
+				errormsg = MAGIC_WUPC;
+				break;
+			}
 		}
 
-		ReaderTransmit(wupC2, sizeof(wupC2), NULL);
-		if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
-			if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("wupC2 error");
-			OnErrorMagic(MAGIC_WUPC);
+		// read block		
+		if ((mifare_sendcmd_short(NULL, 0, ISO14443A_CMD_READBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 18)) {
+			if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("read block send command error");
+			errormsg = 0;
+			break;
 		}
-	}
+		
+		memcpy(data, receivedAnswer, sizeof(data));
+		
+		// send HALT
+		if (workFlags & MAGIC_HALT)
+			mifare_classic_halt_ex(NULL);
 
-	// read block		
-	if ((mifare_sendcmd_short(NULL, 0, ISO14443A_CMD_READBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 18)) {
-		if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("read block send command error");
-		OnErrorMagic(0);
+		isOK = true;
+		break;
 	}
-	
-	memcpy(data, receivedAnswer, sizeof(data));
-	
-	// send HALT
-	if (workFlags & MAGIC_HALT) 
-		mifare_classic_halt_ex(NULL);
-	
-	LED_B_ON();
-	
 	// if MAGIC_DATAIN, the data stays on device side.
-	if (workFlags & MAGIC_DATAIN)
-		memcpy(datain, data, sizeof(data));
-	else
-		cmd_send(CMD_ACK,1,0,0,data,sizeof(data));
+	if (workFlags & MAGIC_DATAIN) {
+		if (isOK)
+			memcpy(datain, data, sizeof(data));
+	} else {
+		if (isOK) 
+			cmd_send(CMD_ACK,1,0,0,data,sizeof(data));	
+		else 
+			OnErrorMagic(errormsg);	
+	}
 	
-	LED_B_OFF();
-
 	if (workFlags & MAGIC_OFF)
 		OnSuccessMagic();
 }
@@ -1313,7 +1373,7 @@ void MifareCIdent(){
 	uint8_t receivedAnswer[1] = {0x00};
 	uint8_t receivedAnswerPar[1] = {0x00};
 
-	ReaderTransmitBitsPar(wupC1,7,0, NULL);
+	ReaderTransmitBitsPar(wupC1, 7, NULL, NULL);
 	if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
 		isOK = false;
 	}
@@ -1338,22 +1398,17 @@ void OnErrorMagic(uint8_t reason){
 	cmd_send(CMD_ACK,0,reason,0,0,0);
 	OnSuccessMagic();
 }
-
-void MifareCollectNonces(uint32_t arg0, uint32_t arg1){
-}
-
 //
 // DESFIRE
 //
-
 void Mifare_DES_Auth1(uint8_t arg0, uint8_t *datain){
-
 	byte_t dataout[12] = {0x00};
 	uint8_t uid[10] = {0x00};
 	uint32_t cuid = 0;
     
 	iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
 	clear_trace();
+	set_tracing(true);
 
 	int len = iso14443a_select_card(uid, NULL, &cuid, true, 0);
 	if(!len) {
@@ -1369,7 +1424,7 @@ void Mifare_DES_Auth1(uint8_t arg0, uint8_t *datain){
 	}
 
 	if (MF_DBGLEVEL >= MF_DBG_EXTENDED) DbpString("AUTH 1 FINISHED");
-    cmd_send(CMD_ACK,1,cuid,0,dataout, sizeof(dataout));
+    cmd_send(CMD_ACK, 1, cuid, 0, dataout, sizeof(dataout));
 }
 
 void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain){
@@ -1394,4 +1449,5 @@ void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain){
 	cmd_send(CMD_ACK, isOK, 0, 0, dataout, sizeof(dataout));
 	FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
 	LEDsoff();
+	set_tracing(FALSE);
 }
\ No newline at end of file