From f885043422facc34eb6a5b3c3767f8ac25338157 Mon Sep 17 00:00:00 2001
From: iceman1001 <iceman@iuse.se>
Date: Fri, 23 Sep 2016 21:28:07 +0200
Subject: [PATCH 1/1] FIX: "hf 14a read" / "hf mf *" / "hf mfdes info"  and
 failure when calling these commands serveral times in row. For long
 transactions the sspclock compare with >1 instead of >=1 ..   Now the timer
 resets properly. CHG: use some #define constants for iso-commands.

---
 armsrc/iso14443a.c     | 11 +++++------
 armsrc/mifarecmd.c     |  5 +----
 armsrc/mifaredesfire.c | 31 +++++++++++--------------------
 armsrc/ticks.c         | 25 ++++++++++---------------
 client/cmdhfmf.c       |  2 +-
 client/cmdlft55xx.c    | 20 ++++++++++++++++----
 6 files changed, 44 insertions(+), 50 deletions(-)

diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c
index 26781095..5a43e233 100644
--- a/armsrc/iso14443a.c
+++ b/armsrc/iso14443a.c
@@ -1835,10 +1835,10 @@ int ReaderReceive(uint8_t *receivedAnswer, uint8_t *parity) {
 // if anticollision is false, then the UID must be provided in uid_ptr[] 
 // and num_cascades must be set (1: 4 Byte UID, 2: 7 Byte UID, 3: 10 Byte UID)
 int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, uint32_t *cuid_ptr, bool anticollision, uint8_t num_cascades) {
-	uint8_t wupa[]       = { 0x52 };  // 0x26 - REQA  0x52 - WAKE-UP
-	uint8_t sel_all[]    = { 0x93,0x20 };
-	uint8_t sel_uid[]    = { 0x93,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
-	uint8_t rats[]       = { 0xE0,0x80,0x00,0x00 }; // FSD=256, FSDI=8, CID=0
+	uint8_t wupa[]       = { ISO14443A_CMD_WUPA };  // 0x26 - ISO14443A_CMD_REQA  0x52 - ISO14443A_CMD_WUPA
+	uint8_t sel_all[]    = { ISO14443A_CMD_ANTICOLL_OR_SELECT,0x20 };
+	uint8_t sel_uid[]    = { ISO14443A_CMD_ANTICOLL_OR_SELECT,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
+	uint8_t rats[]       = { ISO14443A_CMD_RATS,0x80,0x00,0x00 }; // FSD=256, FSDI=8, CID=0
 	uint8_t resp[MAX_FRAME_SIZE] = {0}; // theoretically. A usual RATS will be much smaller
 	uint8_t resp_par[MAX_PARITY_SIZE] = {0};
 	byte_t uid_resp[4] = {0};
@@ -2009,7 +2009,7 @@ void iso14443a_setup(uint8_t fpga_minor_mode) {
 	DemodReset();
 	UartReset();
 	NextTransferTime = 2 * DELAY_ARM2AIR_AS_READER;
-	iso14a_set_timeout(10*106); // 10ms default	
+	iso14a_set_timeout(20*106); // 20ms default	
 }
 
 int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, void *data) {
@@ -2045,7 +2045,6 @@ int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, void *data) {
 
 //-----------------------------------------------------------------------------
 // Read an ISO 14443a tag. Send out commands and store answers.
-//
 //-----------------------------------------------------------------------------
 void ReaderIso14443a(UsbCommand *c) {
 	iso14a_command_t param = c->arg[0];
diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c
index 238bdf8f..49730af9 100644
--- a/armsrc/mifarecmd.c
+++ b/armsrc/mifarecmd.c
@@ -379,7 +379,7 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
 	LED_C_OFF();
 
 	while (true) {
-			if(!iso14443a_select_card(uid, NULL, &cuid, true, 0)) {
+		if(!iso14443a_select_card(uid, NULL, &cuid, true, 0)) {
 			if (MF_DBGLEVEL >= 1)	Dbprintf("Can't select card");
 			break;
 		};
@@ -403,14 +403,11 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
 		break;
 	}
 	
-	//  ----------------------------- crypto1 destroy
 	crypto1_destroy(pcs);
 	
 	if (MF_DBGLEVEL >= 2)	DbpString("WRITE BLOCK FINISHED");
 
-	LED_B_ON();
 	cmd_send(CMD_ACK,isOK,0,0,0,0);
-	LED_B_OFF();
 
 	FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
 	LEDsoff();
diff --git a/armsrc/mifaredesfire.c b/armsrc/mifaredesfire.c
index c5e42277..530b797d 100644
--- a/armsrc/mifaredesfire.c
+++ b/armsrc/mifaredesfire.c
@@ -19,17 +19,13 @@ static  uint8_t deselect_cmd[] = {0xc2,0xe0,0xb4};
 
 bool InitDesfireCard(){
 
+	iso14a_card_select_t card;
+	
 	iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
 	set_tracing(TRUE);
 
-	byte_t cardbuf[USB_CMD_DATA_SIZE] = {0x00};
-	iso14a_card_select_t *card = (iso14a_card_select_t*)cardbuf;
-	
-	int len = iso14443a_select_card(NULL,card,NULL,true,0);
-
-	if (!len) {
-		if (MF_DBGLEVEL >= MF_DBG_ERROR)
-			Dbprintf("Can't select card");
+	if (!iso14443a_select_card(NULL, &card, NULL, true, 0)) {
+		if (MF_DBGLEVEL >= MF_DBG_ERROR) DbpString("Can't select card");
 		OnError(1);
 		return false;
 	}
@@ -92,9 +88,9 @@ void MifareSendCommand(uint8_t arg0, uint8_t arg1, uint8_t *datain){
 void MifareDesfireGetInformation(){
 		
 	int len = 0;
+	iso14a_card_select_t card;
 	uint8_t resp[USB_CMD_DATA_SIZE] = {0x00};
 	uint8_t dataout[USB_CMD_DATA_SIZE] = {0x00};
-	byte_t cardbuf[USB_CMD_DATA_SIZE] = {0x00};
 	
 	/*
 		1 = PCB					1
@@ -110,17 +106,13 @@ void MifareDesfireGetInformation(){
 	iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
 
 	// card select - information
-	iso14a_card_select_t *card = (iso14a_card_select_t*)cardbuf;
-	byte_t isOK = iso14443a_select_card(NULL, card, NULL, true, 0);
-	if ( isOK == 0) {
-		if (MF_DBGLEVEL >= MF_DBG_ERROR) {
-			Dbprintf("Can't select card");
-		}
+	if ( !iso14443a_select_card(NULL, &card, NULL, true, 0) ) {
+		if (MF_DBGLEVEL >= MF_DBG_ERROR) DbpString("Can't select card");
 		OnError(1);
 		return;
 	}
 
-	memcpy(dataout,card->uid,7);
+	memcpy(dataout, card.uid, 7);
 
 	LED_A_ON();
 	LED_B_OFF();
@@ -507,19 +499,17 @@ int DesfireAPDU(uint8_t *cmd, size_t cmd_len, uint8_t *dataout){
 	size_t len = 0;
 	size_t wrappedLen = 0;
 	uint8_t wCmd[USB_CMD_DATA_SIZE] = {0x00};
-	
 	uint8_t resp[MAX_FRAME_SIZE];
     uint8_t par[MAX_PARITY_SIZE];
 	
 	wrappedLen = CreateAPDU( cmd, cmd_len, wCmd);
 	
-	if (MF_DBGLEVEL >= 4) {
+	if (MF_DBGLEVEL >= 4)
 		print_result("WCMD <--: ", wCmd, wrappedLen);	
-	}
+
 	ReaderTransmit( wCmd, wrappedLen, NULL);
 
 	len = ReaderReceive(resp, par);
-	
 	if ( !len ) {
 		if (MF_DBGLEVEL >= 4) Dbprintf("fukked");
 		return FALSE; //DATA LINK ERROR
@@ -566,6 +556,7 @@ size_t CreateAPDU( uint8_t *datain, size_t len, uint8_t *dataout){
 void OnSuccess(){
 	pcb_blocknum = 0;
 	ReaderTransmit(deselect_cmd, 3 , NULL);
+	mifare_ultra_halt();
 	FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
 	LEDsoff();
 	set_tracing(FALSE);	
diff --git a/armsrc/ticks.c b/armsrc/ticks.c
index 4aaa9c98..6f34fe14 100644
--- a/armsrc/ticks.c
+++ b/armsrc/ticks.c
@@ -48,7 +48,7 @@ void SpinDelay(int ms) {
 //	SpinDelay(1000);
 //	ti = GetTickCount() - ti;
 //	Dbprintf("timer(1s): %d t=%d", ti, GetTickCount());
-void StartTickCount() {
+void StartTickCount(void) {
 	// This timer is based on the slow clock. The slow clock frequency is between 22kHz and 40kHz.
 	// We can determine the actual slow clock frequency by looking at the Main Clock Frequency Register.
     uint16_t mainf = AT91C_BASE_PMC->PMC_MCFR & 0xffff;		// = 16 * main clock frequency (16MHz) / slow clock frequency
@@ -60,14 +60,14 @@ void StartTickCount() {
 /*
 * Get the current count.
 */
-uint32_t RAMFUNC GetTickCount(){
+uint32_t RAMFUNC GetTickCount(void){
 	return AT91C_BASE_RTTC->RTTC_RTVR;// was * 2;
 }
 
 //  -------------------------------------------------------------------------
 //  microseconds timer 
 //  -------------------------------------------------------------------------
-void StartCountUS() {
+void StartCountUS(void) {
 	AT91C_BASE_PMC->PMC_PCER |= (1 << 12) | (1 << 13) | (1 << 14);
 	AT91C_BASE_TCB->TCB_BMR = AT91C_TCB_TC0XC0S_NONE | AT91C_TCB_TC1XC1S_TIOA0 | AT91C_TCB_TC2XC2S_NONE;
 
@@ -87,25 +87,20 @@ void StartCountUS() {
 	AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
 	AT91C_BASE_TCB->TCB_BCR = 1;
 	
-	while (AT91C_BASE_TC1->TC_CV > 1);
+	while (AT91C_BASE_TC1->TC_CV >= 1);
 }
 
-uint32_t RAMFUNC GetCountUS(){
+uint32_t RAMFUNC GetCountUS(void){
 	//return (AT91C_BASE_TC1->TC_CV * 0x8000) + ((AT91C_BASE_TC0->TC_CV / 15) * 10);
 	//  By suggestion from PwPiwi, http://www.proxmark.org/forum/viewtopic.php?pid=17548#p17548
 	return (AT91C_BASE_TC1->TC_CV * 0x8000) + ((AT91C_BASE_TC0->TC_CV * 2) / 3); 
 }
-void ResetUSClock(void) {	
-	//enable clock of timer and software trigger
-	AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
-	AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
-	while (AT91C_BASE_TC1->TC_CV > 1);
-}
+
 
 //  -------------------------------------------------------------------------
 //  Timer for iso14443 commands. Uses ssp_clk from FPGA 
 //  -------------------------------------------------------------------------
-void StartCountSspClk() {
+void StartCountSspClk(void) {
 	AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC0) | (1 << AT91C_ID_TC1) | (1 << AT91C_ID_TC2);  // Enable Clock to all timers
 	AT91C_BASE_TCB->TCB_BMR = AT91C_TCB_TC0XC0S_TIOA1 		// XC0 Clock = TIOA1
 							| AT91C_TCB_TC1XC1S_NONE 		// XC1 Clock = none
@@ -160,17 +155,17 @@ void StartCountSspClk() {
 
 	// The high word of the counter (TC2) will not reset until the low word (TC0) overflows. 
 	// Therefore need to wait quite some time before we can use the counter.
-	while (AT91C_BASE_TC2->TC_CV > 1);
+	while (AT91C_BASE_TC2->TC_CV >= 1);
 }
 void ResetSspClk(void) {	
 	//enable clock of timer and software trigger
 	AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
 	AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
 	AT91C_BASE_TC2->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
+	while (AT91C_BASE_TC2->TC_CV >= 1);	
 }
 
-uint32_t RAMFUNC GetCountSspClk(){
-
+uint32_t RAMFUNC GetCountSspClk(void) {
 	uint32_t tmp_count = (AT91C_BASE_TC2->TC_CV << 16) | AT91C_BASE_TC0->TC_CV;
 	if ((tmp_count & 0x0000ffff) == 0)  //small chance that we may have missed an increment in TC2
 		return (AT91C_BASE_TC2->TC_CV << 16);
diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c
index 16dd6f28..6ddf845a 100644
--- a/client/cmdhfmf.c
+++ b/client/cmdhfmf.c
@@ -1050,7 +1050,7 @@ int CmdHF14AMfNestedHard(const char *Cmd) {
 			slow ? "Yes" : "No",
 			tests);
 
-	int16_t isOK = mfnestedhard(blockNo, keyType, key, trgBlockNo, trgKeyType, know_target_key?trgkey:NULL, nonce_file_read, nonce_file_write, slow, tests);
+	int16_t isOK = mfnestedhard(blockNo, keyType, key, trgBlockNo, trgKeyType, know_target_key ? trgkey : NULL, nonce_file_read, nonce_file_write, slow, tests);
 
 	if (isOK) {
 		switch (isOK) {
diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c
index f8865c8d..28149eff 100644
--- a/client/cmdlft55xx.c
+++ b/client/cmdlft55xx.c
@@ -547,6 +547,11 @@ bool tryDetectModulation(){
 		clk = GetAskClock("", FALSE, FALSE);
 		if (clk>0) {
 			tests[hits].ST = TRUE;
+			// "0 0 1 " == clock auto, invert false, maxError 1.
+			// false = no verbose
+			// false = no emSearch
+			// 1 = Ask/Man
+			// st = true
 			if ( ASKDemod_ext("0 0 1", FALSE, FALSE, 1, &tests[hits].ST) && test(DEMOD_ASK, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) {
 				tests[hits].modulation = DEMOD_ASK;
 				tests[hits].bitrate = bitRate;
@@ -555,6 +560,11 @@ bool tryDetectModulation(){
 				++hits;
 			}
 			tests[hits].ST = TRUE;
+			// "0 0 1 " == clock auto, invert true, maxError 1.
+			// false = no verbose
+			// false = no emSearch
+			// 1 = Ask/Man
+			// st = true
 			if ( ASKDemod_ext("0 1 1", FALSE, FALSE, 1, &tests[hits].ST)  && test(DEMOD_ASK, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) {
 				tests[hits].modulation = DEMOD_ASK;
 				tests[hits].bitrate = bitRate;
@@ -1249,8 +1259,11 @@ int CmdT55xxDump(const char *Cmd){
 
 int AquireData( uint8_t page, uint8_t block, bool pwdmode, uint32_t password ){
 	// arg0 bitmodes:
-	// bit0 = pwdmode
-	// bit1 = page to read from
+	// 	bit0 = pwdmode
+	// 	bit1 = page to read from
+	// arg1: which block to read
+	// arg2: password
+	
 	uint8_t arg0 = (page<<1) | pwdmode;
 	UsbCommand c = {CMD_T55XX_READ_BLOCK, {arg0, block, password}};
 	
@@ -1583,8 +1596,7 @@ int CmdT55xxBruteForce(const char *Cmd) {
     return 0;
 }
 
-int tryOnePassword(uint32_t password)
-{
+int tryOnePassword(uint32_t password) {
 	PrintAndLog("Trying password %08x", password);
 	if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, TRUE, password)) {
 		PrintAndLog("Aquireing data from device failed. Quitting");
-- 
2.39.5