]> cvs.zerfleddert.de Git - proxmark3-svn/blobdiff - armsrc/iso14443a.c
Merge pull request #256 from pwpiwi/fast_select
[proxmark3-svn] / armsrc / iso14443a.c
index 7b7314dd81d6246f35fa9246d3ae8fc338dca4ea..b18a2fe60265c0ef5a4750a2c873c0bb8d7f3002 100644 (file)
 // Routines to support ISO 14443 type A.
 //-----------------------------------------------------------------------------
 
+#include "iso14443a.h"
+
 #include "proxmark3.h"
 #include "apps.h"
 #include "util.h"
 #include "string.h"
 #include "cmd.h"
 #include "iso14443crc.h"
-#include "iso14443a.h"
-#include "crapto1.h"
+#include "crapto1/crapto1.h"
 #include "mifareutil.h"
+#include "mifaresniff.h"
 #include "BigBuf.h"
 #include "protocols.h"
+#include "parity.h"
+
+typedef struct {
+       enum {
+               DEMOD_UNSYNCD,
+               // DEMOD_HALF_SYNCD,
+               // DEMOD_MOD_FIRST_HALF,
+               // DEMOD_NOMOD_FIRST_HALF,
+               DEMOD_MANCHESTER_DATA
+       } state;
+       uint16_t twoBits;
+       uint16_t highCnt;
+       uint16_t bitCount;
+       uint16_t collisionPos;
+       uint16_t syncBit;
+       uint8_t  parityBits;
+       uint8_t  parityLen;
+       uint16_t shiftReg;
+       uint16_t samples;
+       uint16_t len;
+       uint32_t startTime, endTime;
+       uint8_t  *output;
+       uint8_t  *parity;
+} tDemod;
+
+typedef enum {
+       MOD_NOMOD = 0,
+       MOD_SECOND_HALF,
+       MOD_FIRST_HALF,
+       MOD_BOTH_HALVES
+       } Modulation_t;
+
+typedef struct {
+       enum {
+               STATE_UNSYNCD,
+               STATE_START_OF_COMMUNICATION,
+               STATE_MILLER_X,
+               STATE_MILLER_Y,
+               STATE_MILLER_Z,
+               // DROP_NONE,
+               // DROP_FIRST_HALF,
+               } state;
+       uint16_t shiftReg;
+       int16_t  bitCount;
+       uint16_t len;
+       uint16_t byteCntMax;
+       uint16_t posCnt;
+       uint16_t syncBit;
+       uint8_t  parityBits;
+       uint8_t  parityLen;
+       uint32_t fourBits;
+       uint32_t startTime, endTime;
+    uint8_t *output;
+       uint8_t *parity;
+} tUart;
 
 static uint32_t iso14a_timeout;
 int rsamples = 0;
@@ -35,7 +92,7 @@ static uint8_t iso14_pcb_blocknum = 0;
 #define REQUEST_GUARD_TIME (7000/16 + 1)
 // minimum time between last modulation of tag and next start bit from reader to tag: 1172 carrier cycles 
 #define FRAME_DELAY_TIME_PICC_TO_PCD (1172/16 + 1) 
-// bool LastCommandWasRequest = FALSE;
+// bool LastCommandWasRequest = false;
 
 //
 // Total delays including SSC-Transfers between ARM and FPGA. These are in carrier clock cycles (1/13,56MHz)
@@ -123,26 +180,6 @@ static uint32_t LastProxToAirDuration;
 #define        SEC_Y 0x00
 #define        SEC_Z 0xc0
 
-const uint8_t OddByteParity[256] = {
-  1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
-  0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
-  0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
-  1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
-  0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
-  1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
-  1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
-  0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
-  0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
-  1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
-  1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
-  0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
-  1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
-  0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
-  0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
-  1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1
-};
-
-
 void iso14a_set_trigger(bool enable) {
        trigger = enable;
 }
@@ -180,11 +217,6 @@ void iso14a_set_ATS_timeout(uint8_t *ats) {
 // Generate the parity value for a byte sequence
 //
 //-----------------------------------------------------------------------------
-byte_t oddparity (const byte_t bt)
-{
-       return OddByteParity[bt];
-}
-
 void GetParity(const uint8_t *pbtCmd, uint16_t iLen, uint8_t *par)
 {
        uint16_t paritybit_cnt = 0;
@@ -193,7 +225,7 @@ void GetParity(const uint8_t *pbtCmd, uint16_t iLen, uint8_t *par)
 
        for (uint16_t i = 0; i < iLen; i++) {
                // Generate the parity bits
-               parityBits |= ((OddByteParity[pbtCmd[i]]) << (7-paritybit_cnt));
+               parityBits |= ((oddparity8(pbtCmd[i])) << (7-paritybit_cnt));
                if (paritybit_cnt == 7) {
                        par[paritybyte_cnt] = parityBits;       // save 8 Bits parity
                        parityBits = 0;                                         // and advance to next Parity Byte
@@ -245,8 +277,8 @@ static tUart Uart;
 // 0111  -   a 2 tick wide pause shifted left
 // 1001  -   a 2 tick wide pause shifted right
 const bool Mod_Miller_LUT[] = {
-       FALSE,  TRUE, FALSE, TRUE,  FALSE, FALSE, FALSE, TRUE,
-       FALSE,  TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE
+       false,  true, false, true,  false, false, false, true,
+       false,  true, false, false, false, false, false, false
 };
 #define IsMillerModulationNibble1(b) (Mod_Miller_LUT[(b & 0x000000F0) >> 4])
 #define IsMillerModulationNibble2(b) (Mod_Miller_LUT[(b & 0x0000000F)])
@@ -356,13 +388,13 @@ static RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time)
                                                Uart.parityBits <<= 1;                                                                  // add a (void) parity bit
                                                Uart.parityBits <<= (8 - (Uart.len&0x0007));                    // left align parity bits
                                                Uart.parity[Uart.parityLen++] = Uart.parityBits;                // and store it
-                                               return TRUE;
+                                               return true;
                                        } else if (Uart.len & 0x0007) {                                                         // there are some parity bits to store
                                                Uart.parityBits <<= (8 - (Uart.len&0x0007));                    // left align remaining parity bits
                                                Uart.parity[Uart.parityLen++] = Uart.parityBits;                // and store them
                                        }
                                        if (Uart.len) {
-                                               return TRUE;                                                                                    // we are finished with decoding the raw data sequence
+                                               return true;                                                                                    // we are finished with decoding the raw data sequence
                                        } else {
                                                UartReset();                                                                                    // Nothing received - start over
                                        }
@@ -390,7 +422,7 @@ static RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time)
                        
        } 
 
-    return FALSE;      // not finished yet, need more data
+    return false;      // not finished yet, need more data
 }
 
 
@@ -415,8 +447,8 @@ static tDemod Demod;
 // Lookup-Table to decide if 4 raw bits are a modulation.
 // We accept three or four "1" in any position
 const bool Mod_Manchester_LUT[] = {
-       FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE,
-       FALSE, FALSE, FALSE, TRUE,  FALSE, TRUE,  TRUE,  TRUE
+       false, false, false, false, false, false, false, true,
+       false, false, false, true,  false, true,  true,  true
 };
 
 #define IsManchesterModulationNibble1(b) (Mod_Manchester_LUT[(b & 0x00F0) >> 4])
@@ -521,13 +553,13 @@ static RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non
                                        Demod.parityBits <<= 1;                                                         // add a (void) parity bit
                                        Demod.parityBits <<= (8 - (Demod.len&0x0007));          // left align remaining parity bits
                                        Demod.parity[Demod.parityLen++] = Demod.parityBits;     // and store them
-                                       return TRUE;
+                                       return true;
                                } else if (Demod.len & 0x0007) {                                                // there are some parity bits to store
                                        Demod.parityBits <<= (8 - (Demod.len&0x0007));          // left align remaining parity bits
                                        Demod.parity[Demod.parityLen++] = Demod.parityBits;     // and store them
                                }
                                if (Demod.len) {
-                                       return TRUE;                                                                            // we are finished with decoding the raw data sequence
+                                       return true;                                                                            // we are finished with decoding the raw data sequence
                                } else {                                                                                                // nothing received. Start over
                                        DemodReset();
                                }
@@ -536,7 +568,7 @@ static RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non
                        
        } 
 
-    return FALSE;      // not finished yet, need more data
+    return false;      // not finished yet, need more data
 }
 
 //=============================================================================
@@ -575,14 +607,14 @@ void RAMFUNC SnoopIso14443a(uint8_t param) {
 
        // init trace buffer
        clear_trace();
-       set_tracing(TRUE);
+       set_tracing(true);
 
        uint8_t *data = dmaBuf;
        uint8_t previous_data = 0;
        int maxDataLen = 0;
        int dataLen = 0;
-       bool TagIsActive = FALSE;
-       bool ReaderIsActive = FALSE;
+       bool TagIsActive = false;
+       bool ReaderIsActive = false;
        
        // Set up the demodulator for tag -> reader responses.
        DemodInit(receivedResponse, receivedResponsePar);
@@ -596,11 +628,11 @@ void RAMFUNC SnoopIso14443a(uint8_t param) {
        // We won't start recording the frames that we acquire until we trigger;
        // a good trigger condition to get started is probably when we see a
        // response from the tag.
-       // triggered == FALSE -- to wait first for card
+       // triggered == false -- to wait first for card
        bool triggered = !(param & 0x03); 
        
        // And now we loop, receiving samples.
-       for(uint32_t rsamples = 0; TRUE; ) {
+       for(uint32_t rsamples = 0; true; ) {
 
                if(BUTTON_PRESS()) {
                        DbpString("cancelled by button");
@@ -649,7 +681,7 @@ void RAMFUNC SnoopIso14443a(uint8_t param) {
                                        LED_C_ON();
 
                                        // check - if there is a short 7bit request from reader
-                                       if ((!triggered) && (param & 0x02) && (Uart.len == 1) && (Uart.bitCount == 7)) triggered = TRUE;
+                                       if ((!triggered) && (param & 0x02) && (Uart.len == 1) && (Uart.bitCount == 7)) triggered = true;
 
                                        if(triggered) {
                                                if (!LogTrace(receivedCmd, 
@@ -657,7 +689,7 @@ void RAMFUNC SnoopIso14443a(uint8_t param) {
                                                                                Uart.startTime*16 - DELAY_READER_AIR2ARM_AS_SNIFFER,
                                                                                Uart.endTime*16 - DELAY_READER_AIR2ARM_AS_SNIFFER,
                                                                                Uart.parity, 
-                                                                               TRUE)) break;
+                                                                               true)) break;
                                        }
                                        /* And ready to receive another command. */
                                        UartReset();
@@ -679,9 +711,9 @@ void RAMFUNC SnoopIso14443a(uint8_t param) {
                                                                        Demod.startTime*16 - DELAY_TAG_AIR2ARM_AS_SNIFFER, 
                                                                        Demod.endTime*16 - DELAY_TAG_AIR2ARM_AS_SNIFFER,
                                                                        Demod.parity,
-                                                                       FALSE)) break;
+                                                                       false)) break;
 
-                                       if ((!triggered) && (param & 0x01)) triggered = TRUE;
+                                       if ((!triggered) && (param & 0x01)) triggered = true;
 
                                        // And ready to receive another response.
                                        DemodReset();
@@ -811,7 +843,7 @@ static void Code4bitAnswerAsTag(uint8_t cmd)
 //-----------------------------------------------------------------------------
 // Wait for commands from reader
 // Stop when button is pressed
-// Or return TRUE when command is captured
+// Or return true when command is captured
 //-----------------------------------------------------------------------------
 static int GetIso14443aCommandFromReader(uint8_t *received, uint8_t *parity, int *len)
 {
@@ -830,13 +862,13 @@ static int GetIso14443aCommandFromReader(uint8_t *received, uint8_t *parity, int
     for(;;) {
         WDT_HIT();
 
-        if(BUTTON_PRESS()) return FALSE;
+        if(BUTTON_PRESS()) return false;
                
         if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
             b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
                        if(MillerDecoding(b, 0)) {
                                *len = Uart.len;
-                               return TRUE;
+                               return true;
                        }
                }
     }
@@ -1046,7 +1078,7 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data)
 
        // clear trace
        clear_trace();
-       set_tracing(TRUE);
+       set_tracing(true);
 
        // Prepare the responses of the anticollision phase
        // there will be not enough time to do this at the moment the reader sends it REQA
@@ -1100,7 +1132,7 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data)
                } else if(receivedCmd[0] == 0x50) {     // Received a HALT
 
                        if (tracing) {
-                               LogTrace(receivedCmd, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
+                               LogTrace(receivedCmd, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true);
                        }
                        p_response = NULL;
                } else if(receivedCmd[0] == 0x60 || receivedCmd[0] == 0x61) {   // Received an authentication request
@@ -1114,7 +1146,7 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data)
                        }
                } else if (order == 7 && len == 8) { // Received {nr] and {ar} (part of authentication)
                        if (tracing) {
-                               LogTrace(receivedCmd, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
+                               LogTrace(receivedCmd, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true);
                        }
                        uint32_t nr = bytes_to_num(receivedCmd,4);
                        uint32_t ar = bytes_to_num(receivedCmd+4,4);
@@ -1158,7 +1190,7 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data)
                                default: {
                                        // Never seen this command before
                                        if (tracing) {
-                                               LogTrace(receivedCmd, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
+                                               LogTrace(receivedCmd, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true);
                                        }
                                        Dbprintf("Received unknown command (len=%d):",len);
                                        Dbhexdump(len,receivedCmd,false);
@@ -1178,7 +1210,7 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data)
                                if (prepare_tag_modulation(&dynamic_response_info,DYNAMIC_MODULATION_BUFFER_SIZE) == false) {
                                        Dbprintf("Error preparing tag response");
                                        if (tracing) {
-                                               LogTrace(receivedCmd, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
+                                               LogTrace(receivedCmd, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true);
                                        }
                                        break;
                                }
@@ -1472,7 +1504,7 @@ static int EmSendCmd14443aRaw(uint8_t *resp, uint16_t respLen, bool correctionNe
 
        // include correction bit if necessary
        if (Uart.parityBits & 0x01) {
-               correctionNeeded = TRUE;
+               correctionNeeded = true;
        }
        if(correctionNeeded) {
                // 1236, so correction bit needed
@@ -1593,18 +1625,18 @@ bool EmLogTrace(uint8_t *reader_data, uint16_t reader_len, uint32_t reader_Start
                uint16_t exact_fdt = (approx_fdt - 20 + 32)/64 * 64 + 20;
                reader_EndTime = tag_StartTime - exact_fdt;
                reader_StartTime = reader_EndTime - reader_modlen;
-               if (!LogTrace(reader_data, reader_len, reader_StartTime, reader_EndTime, reader_Parity, TRUE)) {
-                       return FALSE;
-               } else return(!LogTrace(tag_data, tag_len, tag_StartTime, tag_EndTime, tag_Parity, FALSE));
+               if (!LogTrace(reader_data, reader_len, reader_StartTime, reader_EndTime, reader_Parity, true)) {
+                       return false;
+               } else return(!LogTrace(tag_data, tag_len, tag_StartTime, tag_EndTime, tag_Parity, false));
        } else {
-               return TRUE;
+               return true;
        }
 }
 
 //-----------------------------------------------------------------------------
 // Wait a certain time for tag response
-//  If a response is captured return TRUE
-//  If it takes too long return FALSE
+//  If a response is captured return true
+//  If it takes too long return false
 //-----------------------------------------------------------------------------
 static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receivedResponsePar, uint16_t offset)
 {
@@ -1630,9 +1662,9 @@ static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receive
                        b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
                        if(ManchesterDecoding(b, offset, 0)) {
                                NextTransferTime = MAX(NextTransferTime, Demod.endTime - (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER)/16 + FRAME_DELAY_TIME_PICC_TO_PCD);
-                               return TRUE;
+                               return true;
                        } else if (c++ > iso14a_timeout && Demod.state == DEMOD_UNSYNCD) {
-                               return FALSE
+                               return false
                        }
                }
        }
@@ -1650,7 +1682,7 @@ void ReaderTransmitBitsPar(uint8_t* frame, uint16_t bits, uint8_t *par, uint32_t
   
        // Log reader command in trace buffer
        if (tracing) {
-               LogTrace(frame, nbytes(bits), LastTimeProxToAirStart*16 + DELAY_ARM2AIR_AS_READER, (LastTimeProxToAirStart + LastProxToAirDuration)*16 + DELAY_ARM2AIR_AS_READER, par, TRUE);
+               LogTrace(frame, nbytes(bits), LastTimeProxToAirStart*16 + DELAY_ARM2AIR_AS_READER, (LastTimeProxToAirStart + LastProxToAirDuration)*16 + DELAY_ARM2AIR_AS_READER, par, true);
        }
 }
 
@@ -1680,26 +1712,28 @@ void ReaderTransmit(uint8_t* frame, uint16_t len, uint32_t *timing)
 
 int ReaderReceiveOffset(uint8_t* receivedAnswer, uint16_t offset, uint8_t *parity)
 {
-       if (!GetIso14443aAnswerFromTag(receivedAnswer, parity, offset)) return FALSE;
+       if (!GetIso14443aAnswerFromTag(receivedAnswer, parity, offset)) return false;
        if (tracing) {
-               LogTrace(receivedAnswer, Demod.len, Demod.startTime*16 - DELAY_AIR2ARM_AS_READER, Demod.endTime*16 - DELAY_AIR2ARM_AS_READER, parity, FALSE);
+               LogTrace(receivedAnswer, Demod.len, Demod.startTime*16 - DELAY_AIR2ARM_AS_READER, Demod.endTime*16 - DELAY_AIR2ARM_AS_READER, parity, false);
        }
        return Demod.len;
 }
 
 int ReaderReceive(uint8_t *receivedAnswer, uint8_t *parity)
 {
-       if (!GetIso14443aAnswerFromTag(receivedAnswer, parity, 0)) return FALSE;
+       if (!GetIso14443aAnswerFromTag(receivedAnswer, parity, 0)) return false;
        if (tracing) {
-               LogTrace(receivedAnswer, Demod.len, Demod.startTime*16 - DELAY_AIR2ARM_AS_READER, Demod.endTime*16 - DELAY_AIR2ARM_AS_READER, parity, FALSE);
+               LogTrace(receivedAnswer, Demod.len, Demod.startTime*16 - DELAY_AIR2ARM_AS_READER, Demod.endTime*16 - DELAY_AIR2ARM_AS_READER, parity, false);
        }
        return Demod.len;
 }
 
-/* performs iso14443a anticollision procedure
- * fills the uid pointer unless NULL
- * fills resp_data unless NULL */
-int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, uint32_t *cuid_ptr) {
+// performs iso14443a anticollision (optional) and card select procedure
+// fills the uid and cuid pointer unless NULL
+// fills the card info record unless NULL
+// 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};
@@ -1714,7 +1748,7 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u
        int len;
 
        // Broadcast for a card, WUPA (0x52) will force response from all cards in the field
-    ReaderTransmitBitsPar(wupa,7,0, NULL);
+    ReaderTransmitBitsPar(wupa, 7, NULL, NULL);
        
        // Receive the ATQA
        if(!ReaderReceive(resp, resp_par)) return 0;
@@ -1725,9 +1759,11 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u
                memset(p_hi14a_card->uid,0,10);
        }
 
-       // clear uid
-       if (uid_ptr) {
-               memset(uid_ptr,0,10);
+       if (anticollision) {
+               // clear uid
+               if (uid_ptr) {
+                       memset(uid_ptr,0,10);
+               }
        }
 
        // check for proprietary anticollision:
@@ -1742,40 +1778,49 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u
                // SELECT_* (L1: 0x93, L2: 0x95, L3: 0x97)
                sel_uid[0] = sel_all[0] = 0x93 + cascade_level * 2;
 
-               // SELECT_ALL
-               ReaderTransmit(sel_all, sizeof(sel_all), NULL);
-               if (!ReaderReceive(resp, resp_par)) return 0;
-
-               if (Demod.collisionPos) {                       // we had a collision and need to construct the UID bit by bit
-                       memset(uid_resp, 0, 4);
-                       uint16_t uid_resp_bits = 0;
-                       uint16_t collision_answer_offset = 0;
-                       // anti-collision-loop:
-                       while (Demod.collisionPos) {
-                               Dbprintf("Multiple tags detected. Collision after Bit %d", Demod.collisionPos);
-                               for (uint16_t i = collision_answer_offset; i < Demod.collisionPos; i++, uid_resp_bits++) {      // add valid UID bits before collision point
-                                       uint16_t UIDbit = (resp[i/8] >> (i % 8)) & 0x01;
-                                       uid_resp[uid_resp_bits / 8] |= UIDbit << (uid_resp_bits % 8);
+               if (anticollision) {
+                       // SELECT_ALL
+                       ReaderTransmit(sel_all, sizeof(sel_all), NULL);
+                       if (!ReaderReceive(resp, resp_par)) return 0;
+
+                       if (Demod.collisionPos) {                       // we had a collision and need to construct the UID bit by bit
+                               memset(uid_resp, 0, 4);
+                               uint16_t uid_resp_bits = 0;
+                               uint16_t collision_answer_offset = 0;
+                               // anti-collision-loop:
+                               while (Demod.collisionPos) {
+                                       Dbprintf("Multiple tags detected. Collision after Bit %d", Demod.collisionPos);
+                                       for (uint16_t i = collision_answer_offset; i < Demod.collisionPos; i++, uid_resp_bits++) {      // add valid UID bits before collision point
+                                               uint16_t UIDbit = (resp[i/8] >> (i % 8)) & 0x01;
+                                               uid_resp[uid_resp_bits / 8] |= UIDbit << (uid_resp_bits % 8);
+                                       }
+                                       uid_resp[uid_resp_bits/8] |= 1 << (uid_resp_bits % 8);                                  // next time select the card(s) with a 1 in the collision position
+                                       uid_resp_bits++;
+                                       // construct anticollosion command:
+                                       sel_uid[1] = ((2 + uid_resp_bits/8) << 4) | (uid_resp_bits & 0x07);     // length of data in bytes and bits
+                                       for (uint16_t i = 0; i <= uid_resp_bits/8; i++) {
+                                               sel_uid[2+i] = uid_resp[i];
+                                       }
+                                       collision_answer_offset = uid_resp_bits%8;
+                                       ReaderTransmitBits(sel_uid, 16 + uid_resp_bits, NULL);
+                                       if (!ReaderReceiveOffset(resp, collision_answer_offset, resp_par)) return 0;
                                }
-                               uid_resp[uid_resp_bits/8] |= 1 << (uid_resp_bits % 8);                                  // next time select the card(s) with a 1 in the collision position
-                               uid_resp_bits++;
-                               // construct anticollosion command:
-                               sel_uid[1] = ((2 + uid_resp_bits/8) << 4) | (uid_resp_bits & 0x07);     // length of data in bytes and bits
-                               for (uint16_t i = 0; i <= uid_resp_bits/8; i++) {
-                                       sel_uid[2+i] = uid_resp[i];
+                               // finally, add the last bits and BCC of the UID
+                               for (uint16_t i = collision_answer_offset; i < (Demod.len-1)*8; i++, uid_resp_bits++) {
+                                       uint16_t UIDbit = (resp[i/8] >> (i%8)) & 0x01;
+                                       uid_resp[uid_resp_bits/8] |= UIDbit << (uid_resp_bits % 8);
                                }
-                               collision_answer_offset = uid_resp_bits%8;
-                               ReaderTransmitBits(sel_uid, 16 + uid_resp_bits, NULL);
-                               if (!ReaderReceiveOffset(resp, collision_answer_offset, resp_par)) return 0;
+
+                       } else {                // no collision, use the response to SELECT_ALL as current uid
+                               memcpy(uid_resp, resp, 4);
                        }
-                       // finally, add the last bits and BCC of the UID
-                       for (uint16_t i = collision_answer_offset; i < (Demod.len-1)*8; i++, uid_resp_bits++) {
-                               uint16_t UIDbit = (resp[i/8] >> (i%8)) & 0x01;
-                               uid_resp[uid_resp_bits/8] |= UIDbit << (uid_resp_bits % 8);
+               } else {
+                       if (cascade_level < num_cascades - 1) {
+                               uid_resp[0] = 0x88;
+                               memcpy(uid_resp+1, uid_ptr+cascade_level*3, 3);
+                       } else {
+                               memcpy(uid_resp, uid_ptr+cascade_level*3, 4);
                        }
-
-               } else {                // no collision, use the response to SELECT_ALL as current uid
-                       memcpy(uid_resp, resp, 4);
                }
                uid_resp_len = 4;
 
@@ -1786,7 +1831,7 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u
 
                // Construct SELECT UID command
                sel_uid[1] = 0x70;                                                                                                      // transmitting a full UID (1 Byte cmd, 1 Byte NVB, 4 Byte UID, 1 Byte BCC, 2 Bytes CRC)
-               memcpy(sel_uid+2, uid_resp, 4);                                                                         // the UID
+               memcpy(sel_uid+2, uid_resp, 4);                                                                         // the UID received during anticollision, or the provided UID
                sel_uid[6] = sel_uid[2] ^ sel_uid[3] ^ sel_uid[4] ^ sel_uid[5];         // calculate and add BCC
                AppendCrc14443a(sel_uid, 7);                                                                            // calculate and add CRC
                ReaderTransmit(sel_uid, sizeof(sel_uid), NULL);
@@ -1794,19 +1839,18 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u
                // Receive the SAK
                if (!ReaderReceive(resp, resp_par)) return 0;
                sak = resp[0];
-
-    // Test if more parts of the uid are coming
+       
+               // Test if more parts of the uid are coming
                if ((sak & 0x04) /* && uid_resp[0] == 0x88 */) {
                        // Remove first byte, 0x88 is not an UID byte, it CT, see page 3 of:
                        // http://www.nxp.com/documents/application_note/AN10927.pdf
                        uid_resp[0] = uid_resp[1];
                        uid_resp[1] = uid_resp[2];
                        uid_resp[2] = uid_resp[3]; 
-
                        uid_resp_len = 3;
                }
 
-               if(uid_ptr) {
+               if(uid_ptr && anticollision) {
                        memcpy(uid_ptr + (cascade_level*3), uid_resp, uid_resp_len);
                }
 
@@ -1917,17 +1961,17 @@ void ReaderIso14443a(UsbCommand *c)
                clear_trace();
        }
 
-       set_tracing(TRUE);
+       set_tracing(true);
 
        if(param & ISO14A_REQUEST_TRIGGER) {
-               iso14a_set_trigger(TRUE);
+               iso14a_set_trigger(true);
        }
 
        if(param & ISO14A_CONNECT) {
                iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
                if(!(param & ISO14A_NO_SELECT)) {
                        iso14a_card_select_t *card = (iso14a_card_select_t*)buf;
-                       arg0 = iso14443a_select_card(NULL,card,NULL);
+                       arg0 = iso14443a_select_card(NULL, card, NULL, true, 0);
                        cmd_send(CMD_ACK,arg0,card->uidlen,0,buf,sizeof(iso14a_card_select_t));
                }
        }
@@ -1981,7 +2025,7 @@ void ReaderIso14443a(UsbCommand *c)
        }
 
        if(param & ISO14A_REQUEST_TRIGGER) {
-               iso14a_set_trigger(FALSE);
+               iso14a_set_trigger(false);
        }
 
        if(param & ISO14A_NO_DISCONNECT) {
@@ -2041,12 +2085,12 @@ void ReaderMifare(bool first_try)
        BigBuf_free();
        
        clear_trace();
-       set_tracing(TRUE);
+       set_tracing(true);
 
        byte_t nt_diff = 0;
        uint8_t par[1] = {0};   // maximum 8 Bytes to be sent here, 1 byte parity is therefore enough
        static byte_t par_low = 0;
-       bool led_on = TRUE;
+       bool led_on = true;
        uint8_t uid[10]  ={0};
        uint32_t cuid;
 
@@ -2096,7 +2140,7 @@ void ReaderMifare(bool first_try)
        uint32_t select_time;
        uint32_t halt_time;
        
-       for(uint16_t i = 0; TRUE; i++) {
+       for(uint16_t i = 0; true; i++) {
                
                LED_C_ON();
                WDT_HIT();
@@ -2124,7 +2168,7 @@ void ReaderMifare(bool first_try)
                        SpinDelay(100);
                }
                
-               if(!iso14443a_select_card(uid, NULL, &cuid)) {
+               if(!iso14443a_select_card(uid, NULL, &cuid, true, 0)) {
                        if (MF_DBGLEVEL >= 1)   Dbprintf("Mifare: Can't select card");
                        continue;
                }
@@ -2305,7 +2349,7 @@ void ReaderMifare(bool first_try)
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
        LEDsoff();
 
-       set_tracing(FALSE);
+       set_tracing(false);
 }
 
 typedef struct {
@@ -2329,6 +2373,7 @@ typedef struct {
   * FLAG_7B_UID_IN_DATA - means that there is a 7-byte UID in the data-section, we're expected to use that
   * FLAG_10B_UID_IN_DATA       - use 10-byte UID in the data-section not finished
   *    FLAG_NR_AR_ATTACK  - means we should collect NR_AR responses for bruteforcing later
+  * FLAG_RANDOM_NONCE - means we should generate some pseudo-random nonce data (only allows moebius attack)
   *@param exitAfterNReads, exit simulation after n blocks have been read, 0 is infinite ...
   * (unless reader attack mode enabled then it runs util it gets enough nonces to recover all keys attmpted)
   */
@@ -2336,7 +2381,6 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
 {
        int cardSTATE = MFEMUL_NOFIELD;
        int _UID_LEN = 0; // 4, 7, 10
-       int _7BUID = 0;
        int vHf = 0;    // in mV
        int res;
        uint32_t selTimer = 0;
@@ -2360,14 +2404,13 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
        uint8_t response[MAX_MIFARE_FRAME_SIZE];
        uint8_t response_par[MAX_MIFARE_PARITY_SIZE];
        
-       uint8_t rATQA[] = {0x04, 0x00}; // Mifare classic 1k 4BUID
+       uint8_t rATQA[]    = {0x04, 0x00}; // Mifare classic 1k 4BUID
        uint8_t rUIDBCC1[] = {0xde, 0xad, 0xbe, 0xaf, 0x62};
        uint8_t rUIDBCC2[] = {0xde, 0xad, 0xbe, 0xaf, 0x62}; // !!!
        uint8_t rUIDBCC3[] = {0xde, 0xad, 0xbe, 0xaf, 0x62};
 
-       uint8_t rSAK[] = {0x08, 0xb6, 0xdd};
-       uint8_t rSAK1[] = {0x04, 0xda, 0x17};
-       uint8_t rSAK2[] = {0x04, 0xda, 0x17}; //need to look up
+       uint8_t rSAKfinal[]= {0x08, 0xb6, 0xdd};      // mifare 1k indicated
+       uint8_t rSAK1[]    = {0x04, 0xda, 0x17};      // indicate UID not finished
 
        uint8_t rAUTH_NT[] = {0x01, 0x02, 0x03, 0x04};
        uint8_t rAUTH_AT[] = {0x00, 0x00, 0x00, 0x00};
@@ -2375,21 +2418,26 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
        //Here, we collect UID,sector,keytype,NT,AR,NR,NT2,AR2,NR2
        // This will be used in the reader-only attack.
 
-       //allow collecting up to 8 sets of nonces to allow recovery of 8 keys
-       #define ATTACK_KEY_COUNT 8
-       nonces_t ar_nr_resp[ATTACK_KEY_COUNT*2]; //*2 for 2 separate attack types
+       //allow collecting up to 8 sets of nonces to allow recovery of up to 8 keys
+       #define ATTACK_KEY_COUNT 8 // keep same as define in cmdhfmf.c -> readerAttack()
+       nonces_t ar_nr_resp[ATTACK_KEY_COUNT*2]; //*2 for 2 separate attack types (nml, moebius)
        memset(ar_nr_resp, 0x00, sizeof(ar_nr_resp));
 
-       uint8_t ar_nr_collected[ATTACK_KEY_COUNT*2];
+       uint8_t ar_nr_collected[ATTACK_KEY_COUNT*2]; //*2 for 2nd attack type (moebius)
        memset(ar_nr_collected, 0x00, sizeof(ar_nr_collected));
-       bool collectMoebius = false;
        uint8_t nonce1_count = 0;
        uint8_t nonce2_count = 0;
        uint8_t moebius_n_count = 0;
+       bool gettingMoebius = false;
        uint8_t mM = 0; //moebius_modifier for collection storage
 
        // Authenticate response - nonce
-       uint32_t nonce = bytes_to_num(rAUTH_NT, 4);
+       uint32_t nonce;
+       if (flags & FLAG_RANDOM_NONCE) {
+               nonce = prand();
+       } else {
+               nonce = bytes_to_num(rAUTH_NT, 4);
+       }
        
        //-- Determine the UID
        // Can be set from emulator memory, incoming data
@@ -2404,7 +2452,6 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
                // 7B uid comes from data-portion of packet
                memcpy(&rUIDBCC1[1],datain,3);
                memcpy(rUIDBCC2, datain+3, 4);
-               _7BUID = true;
                _UID_LEN = 7;
        } else if (flags & FLAG_10B_UID_IN_DATA) {
                memcpy(&rUIDBCC1[1], datain,   3);
@@ -2414,8 +2461,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
        } else {
                // get UID from emul memory - guess at length
                emlGetMemBt(receivedCmd, 7, 1);
-               _7BUID = !(receivedCmd[0] == 0x00);
-               if (!_7BUID) {                     // ---------- 4BUID
+               if (receivedCmd[0] == 0x00) {      // ---------- 4BUID
                        emlGetMemBt(rUIDBCC1, 0, 4);
                        _UID_LEN = 4;
                } else {                           // ---------- 7BUID
@@ -2501,10 +2547,11 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
 
        // clear trace
        clear_trace();
-       set_tracing(TRUE);
+       set_tracing(true);
 
-       bool finished = FALSE;
-       while (!BUTTON_PRESS() && !finished && !usb_poll_validate_length()) {
+       bool finished = false;
+       bool button_pushed = BUTTON_PRESS();
+       while (!button_pushed && !finished && !usb_poll_validate_length()) {
                WDT_HIT();
 
                // find reader field
@@ -2514,7 +2561,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
                                cardSTATE_TO_IDLE();
                                LED_A_ON();
                        }
-               } 
+               }
                if (cardSTATE == MFEMUL_NOFIELD) continue;
 
                //Now, get data
@@ -2526,7 +2573,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
                } else if (res == 1) {
                        break;  //return value 1 means button press
                }
-                       
+
                // REQ or WUP request in ANY state and WUP in HALTED state
                if (len == 1 && ((receivedCmd[0] == ISO14443A_CMD_REQA && cardSTATE != MFEMUL_HALTED) || receivedCmd[0] == ISO14443A_CMD_WUPA)) {
                        selTimer = GetTickCount();
@@ -2538,6 +2585,9 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
                        LED_C_OFF();
                        crypto1_destroy(pcs);
                        cardAUTHKEY = 0xff;
+                       if (flags & FLAG_RANDOM_NONCE) {
+                               nonce = prand();
+                       }
                        continue;
                }
                
@@ -2545,31 +2595,29 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
                        case MFEMUL_NOFIELD:
                        case MFEMUL_HALTED:
                        case MFEMUL_IDLE:{
-                               LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
+                               LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true);
                                break;
                        }
                        case MFEMUL_SELECT1:{
-                               // select all
-                               if (len == 2 && (receivedCmd[0] == 0x93 && receivedCmd[1] == 0x20)) {
+                               // select all - 0x93 0x20
+                               if (len == 2 && (receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT && receivedCmd[1] == 0x20)) {
                                        if (MF_DBGLEVEL >= 4)   Dbprintf("SELECT ALL received");
                                        EmSendCmd(rUIDBCC1, sizeof(rUIDBCC1));
                                        break;
                                }
 
-                               if (MF_DBGLEVEL >= 4 && len == 9 && receivedCmd[0] == 0x93 && receivedCmd[1] == 0x70 )
-                               {
-                                       Dbprintf("SELECT %02x%02x%02x%02x received",receivedCmd[2],receivedCmd[3],receivedCmd[4],receivedCmd[5]);
-                               }
-                               // select card
-                               // check correct sak values... (marshmellow)
-                               if (len == 9 && 
-                                               (receivedCmd[0] == 0x93 && receivedCmd[1] == 0x70 && memcmp(&receivedCmd[2], rUIDBCC1, 4) == 0)) {
+                               // select card - 0x93 0x70 ...
+                               if (len == 9 &&
+                                               (receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT && receivedCmd[1] == 0x70 && memcmp(&receivedCmd[2], rUIDBCC1, 4) == 0)) {
+                                       if (MF_DBGLEVEL >= 4) 
+                                               Dbprintf("SELECT %02x%02x%02x%02x received",receivedCmd[2],receivedCmd[3],receivedCmd[4],receivedCmd[5]);
+                                       
                                        switch(_UID_LEN) {
                                                case 4:
                                                        cardSTATE = MFEMUL_WORK;
                                                        LED_B_ON();
                                                        if (MF_DBGLEVEL >= 4)   Dbprintf("--> WORK. anticol1 time: %d", GetTickCount() - selTimer);
-                                                       EmSendCmd(rSAK, sizeof(rSAK));
+                                                       EmSendCmd(rSAKfinal, sizeof(rSAKfinal));
                                                        break;
                                                case 7:
                                                        cardSTATE       = MFEMUL_SELECT2;
@@ -2577,7 +2625,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
                                                        break;
                                                case 10:
                                                        cardSTATE       = MFEMUL_SELECT2;
-                                                       EmSendCmd(rSAK2, sizeof(rSAK2));
+                                                       EmSendCmd(rSAK1, sizeof(rSAK1));
                                                        break;
                                                default:break;
                                        }
@@ -2588,19 +2636,21 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
                        }
                        case MFEMUL_SELECT3:{
                                if (!len) { 
-                                       LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
+                                       LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true);
                                        break;
                                }
+                               // select all cl3 - 0x97 0x20
                                if (len == 2 && (receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_3 && receivedCmd[1] == 0x20)) {
                                        EmSendCmd(rUIDBCC3, sizeof(rUIDBCC3));
                                        break;
                                }
+                               // select card cl3 - 0x97 0x70
                                if (len == 9 && 
                                                (receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_3 &&
                                                 receivedCmd[1] == 0x70 && 
                                                 memcmp(&receivedCmd[2], rUIDBCC3, 4) == 0) ) {
 
-                                       EmSendCmd(rSAK2, sizeof(rSAK2));
+                                       EmSendCmd(rSAKfinal, sizeof(rSAKfinal));
                                        cardSTATE = MFEMUL_WORK;
                                        LED_B_ON();
                                        if (MF_DBGLEVEL >= 4)   Dbprintf("--> WORK. anticol3 time: %d", GetTickCount() - selTimer);
@@ -2610,20 +2660,19 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
                                break;
                        }
                        case MFEMUL_AUTH1:{
-                               if( len != 8)
-                               {
+                               if( len != 8) {
                                        cardSTATE_TO_IDLE();
-                                       LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
+                                       LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true);
                                        break;
                                }
 
                                uint32_t nr = bytes_to_num(receivedCmd, 4);
                                uint32_t ar = bytes_to_num(&receivedCmd[4], 4);
        
-                               //Collect AR/NR per keytype & sector
+                               // Collect AR/NR per keytype & sector
                                if(flags & FLAG_NR_AR_ATTACK) {
                                        for (uint8_t i = 0; i < ATTACK_KEY_COUNT; i++) {
-                                               if ( ar_nr_collected[i+mM]==0 || (cardAUTHSC == ar_nr_resp[i+mM].sector && cardAUTHKEY == ar_nr_resp[i+mM].keytype && ar_nr_collected[i+mM] > 0) ) {
+                                               if ( ar_nr_collected[i+mM]==0 || ((cardAUTHSC == ar_nr_resp[i+mM].sector) && (cardAUTHKEY == ar_nr_resp[i+mM].keytype) && (ar_nr_collected[i+mM] > 0)) ) {
                                                        // if first auth for sector, or matches sector and keytype of previous auth
                                                        if (ar_nr_collected[i+mM] < 2) {
                                                                // if we haven't already collected 2 nonces for this sector
@@ -2638,7 +2687,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
                                                                                ar_nr_resp[i+mM].nr = nr;
                                                                                ar_nr_resp[i+mM].ar = ar;
                                                                                nonce1_count++;
-                                                                               //add this nonce to first moebius nonce
+                                                                               // add this nonce to first moebius nonce
                                                                                ar_nr_resp[i+ATTACK_KEY_COUNT].cuid = cuid;
                                                                                ar_nr_resp[i+ATTACK_KEY_COUNT].sector = cardAUTHSC;
                                                                                ar_nr_resp[i+ATTACK_KEY_COUNT].keytype = cardAUTHKEY;
@@ -2646,35 +2695,42 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
                                                                                ar_nr_resp[i+ATTACK_KEY_COUNT].nr = nr;
                                                                                ar_nr_resp[i+ATTACK_KEY_COUNT].ar = ar;
                                                                                ar_nr_collected[i+ATTACK_KEY_COUNT]++;
-                                                                       } else { //second nonce collect (std and moebius)
+                                                                       } else { // second nonce collect (std and moebius)
                                                                                ar_nr_resp[i+mM].nonce2 = nonce;
                                                                                ar_nr_resp[i+mM].nr2 = nr;
                                                                                ar_nr_resp[i+mM].ar2 = ar;
-                                                                               if (!collectMoebius) {
+                                                                               if (!gettingMoebius) {
                                                                                        nonce2_count++;
-                                                                                       //check if this was the last second nonce we need for std attack
+                                                                                       // check if this was the last second nonce we need for std attack
                                                                                        if ( nonce2_count == nonce1_count ) {
-                                                                                               //done collecting std test switch to moebius
-                                                                                               collectMoebius = true;
+                                                                                               // done collecting std test switch to moebius
+                                                                                               // first finish incrementing last sample
+                                                                                               ar_nr_collected[i+mM]++; 
+                                                                                               // switch to moebius collection
+                                                                                               gettingMoebius = true;
                                                                                                mM = ATTACK_KEY_COUNT;
-                                                                                               nonce = nonce*7;
+                                                                                               if (flags & FLAG_RANDOM_NONCE) {
+                                                                                                       nonce = prand();
+                                                                                               } else {
+                                                                                                       nonce = nonce*7;
+                                                                                               }
+                                                                                               break;
                                                                                        }
                                                                                } else {
                                                                                        moebius_n_count++;
-                                                                                       //if we've collected all the nonces we need - finish.
+                                                                                       // if we've collected all the nonces we need - finish.
                                                                                        if (nonce1_count == moebius_n_count) finished = true;
                                                                                }
                                                                        }
                                                                        ar_nr_collected[i+mM]++;
-                                                                       break;
                                                                }
-                                                       } else { //already collected 2 nonces for sector - reader looping? - quit
-                                                               //finished = true;
                                                        }
+                                                       // we found right spot for this nonce stop looking
+                                                       break;
                                                }
                                        }
                                }
-       
+
                                // --- crypto
                                crypto1_word(pcs, nr , 1);
                                cardRr = ar ^ crypto1_word(pcs, 0, 0);
@@ -2689,7 +2745,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
                                        // reader to do a WUPA after a while. /Martin
                                        // -- which is the correct response. /piwi
                                        cardSTATE_TO_IDLE();
-                                       LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
+                                       LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true);
                                        break;
                                }
 
@@ -2708,26 +2764,27 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
                        }
                        case MFEMUL_SELECT2:{
                                if (!len) { 
-                                       LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
+                                       LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true);
                                        break;
-                               }
-                               if (len == 2 && (receivedCmd[0] == 0x95 && receivedCmd[1] == 0x20)) {
+                               }       
+                               // select all cl2 - 0x95 0x20
+                               if (len == 2 && (receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_2 && receivedCmd[1] == 0x20)) {
                                        EmSendCmd(rUIDBCC2, sizeof(rUIDBCC2));
                                        break;
                                }
 
-                               // select 2 card
+                               // select cl2 card - 0x95 0x70 xxxxxxxxxxxx
                                if (len == 9 && 
-                                               (receivedCmd[0] == 0x95 && receivedCmd[1] == 0x70 && memcmp(&receivedCmd[2], rUIDBCC2, 4) == 0)) {
-                                       //which sak now? (marshmellow)
-                                       EmSendCmd(rSAK, sizeof(rSAK));
+                                               (receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_2 && receivedCmd[1] == 0x70 && memcmp(&receivedCmd[2], rUIDBCC2, 4) == 0)) {
                                        switch(_UID_LEN) {
                                                case 7:
+                                                       EmSendCmd(rSAKfinal, sizeof(rSAKfinal));
                                                        cardSTATE = MFEMUL_WORK;
                                                        LED_B_ON();
                                                        if (MF_DBGLEVEL >= 4)   Dbprintf("--> WORK. anticol2 time: %d", GetTickCount() - selTimer);
                                                        break;
                                                case 10:
+                                                       EmSendCmd(rSAK1, sizeof(rSAK1));
                                                        cardSTATE = MFEMUL_SELECT3;
                                                        break;
                                                default:break;
@@ -2737,7 +2794,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
                                
                                // i guess there is a command). go into the work state.
                                if (len != 4) {
-                                       LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
+                                       LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true);
                                        break;
                                }
                                cardSTATE = MFEMUL_WORK;
@@ -2747,7 +2804,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
 
                        case MFEMUL_WORK:{
                                if (len == 0) {
-                                       LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
+                                       LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true);
                                        break;
                                }
                                
@@ -2759,7 +2816,9 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
                                }
                                
                                if (len == 4 && (receivedCmd[0] == 0x60 || receivedCmd[0] == 0x61)) {
-                                       if (receivedCmd[1] >= 16 * 4) {
+
+                                       // if authenticating to a block that shouldn't exist - as long as we are not doing the reader attack
+                                       if (receivedCmd[1] >= 16 * 4 && !(flags & FLAG_NR_AR_ATTACK)) {
                                                //is this the correct response to an auth on a out of range block? marshmellow
                                                EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA));
                                                if (MF_DBGLEVEL >= 2) Dbprintf("Reader tried to operate (0x%02x) on out of range block: %d (0x%02x), nacking",receivedCmd[0],receivedCmd[1],receivedCmd[1]);
@@ -2805,7 +2864,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
                                }
                                
                                if(len != 4) {
-                                       LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
+                                       LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true);
                                        break;
                                }
 
@@ -2884,7 +2943,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
                                        LED_C_OFF();
                                        cardSTATE = MFEMUL_HALTED;
                                        if (MF_DBGLEVEL >= 4)   Dbprintf("--> HALTED. Selected time: %d ms",  GetTickCount() - selTimer);
-                                       LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
+                                       LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true);
                                        break;
                                }
                                // RATS
@@ -2905,7 +2964,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
                                        cardSTATE = MFEMUL_WORK;
                                } else {
                                        cardSTATE_TO_IDLE();
-                                       LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
+                                       LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true);
                                }
                                break;
                        }
@@ -2918,7 +2977,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
                                        cardSTATE_TO_IDLE();
                                        break;
                                } 
-                               LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
+                               LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true);
                                cardINTREG = cardINTREG + ans;
                                cardSTATE = MFEMUL_WORK;
                                break;
@@ -2931,7 +2990,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
                                        cardSTATE_TO_IDLE();
                                        break;
                                }
-                               LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
+                               LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true);
                                cardINTREG = cardINTREG - ans;
                                cardSTATE = MFEMUL_WORK;
                                break;
@@ -2944,18 +3003,18 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
                                        cardSTATE_TO_IDLE();
                                        break;
                                }
-                               LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
+                               LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true);
                                cardSTATE = MFEMUL_WORK;
                                break;
                        }
                }
+               button_pushed = BUTTON_PRESS();
        }
 
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
        LEDsoff();
 
-       if(flags & FLAG_NR_AR_ATTACK && MF_DBGLEVEL >= 1)
-       {
+       if(flags & FLAG_NR_AR_ATTACK && MF_DBGLEVEL >= 1) {
                for ( uint8_t   i = 0; i < ATTACK_KEY_COUNT; i++) {
                        if (ar_nr_collected[i] == 2) {
                                Dbprintf("Collected two pairs of AR/NR which can be used to extract %s from reader for sector %d:", (i<ATTACK_KEY_COUNT/2) ? "keyA" : "keyB", ar_nr_resp[i].sector);
@@ -2986,16 +3045,13 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
        }
        if (MF_DBGLEVEL >= 1)   Dbprintf("Emulator stopped. Tracing: %d  trace length: %d ",    tracing, BigBuf_get_traceLen());
 
-       if(flags & FLAG_INTERACTIVE)// Interactive mode flag, means we need to send ACK
-       {
+       if(flags & FLAG_INTERACTIVE) { // Interactive mode flag, means we need to send ACK
                //Send the collected ar_nr in the response
-               cmd_send(CMD_ACK,CMD_SIMULATE_MIFARE_CARD,0,0,&ar_nr_resp,sizeof(ar_nr_resp));
+               cmd_send(CMD_ACK,CMD_SIMULATE_MIFARE_CARD,button_pushed,0,&ar_nr_resp,sizeof(ar_nr_resp));
        }
-       
 }
 
 
-
 //-----------------------------------------------------------------------------
 // MIFARE sniffer. 
 // 
@@ -3009,7 +3065,7 @@ void RAMFUNC SniffMifare(uint8_t param) {
        LEDsoff();
        // init trace buffer
        clear_trace();
-       set_tracing(TRUE);
+       set_tracing(true);
 
        // The command (reader -> tag) that we're receiving.
        // The length of a received command will in most cases be no more than 18 bytes.
@@ -3030,8 +3086,8 @@ void RAMFUNC SniffMifare(uint8_t param) {
        uint8_t previous_data = 0;
        int maxDataLen = 0;
        int dataLen = 0;
-       bool ReaderIsActive = FALSE;
-       bool TagIsActive = FALSE;
+       bool ReaderIsActive = false;
+       bool TagIsActive = false;
 
        // Set up the demodulator for tag -> reader responses.
        DemodInit(receivedResponse, receivedResponsePar);
@@ -3048,7 +3104,7 @@ void RAMFUNC SniffMifare(uint8_t param) {
        MfSniffInit();
 
        // And now we loop, receiving samples.
-       for(uint32_t sniffCounter = 0; TRUE; ) {
+       for(uint32_t sniffCounter = 0; true; ) {
        
                if(BUTTON_PRESS()) {
                        DbpString("cancelled by button");
@@ -3066,8 +3122,8 @@ void RAMFUNC SniffMifare(uint8_t param) {
                                sniffCounter = 0;
                                data = dmaBuf;
                                maxDataLen = 0;
-                               ReaderIsActive = FALSE;
-                               TagIsActive = FALSE;
+                               ReaderIsActive = false;
+                               TagIsActive = false;
                                FpgaSetupSscDma((uint8_t *)dmaBuf, DMA_BUFFER_SIZE); // set transfer address and number of bytes. Start transfer.
                        }
                }
@@ -3109,7 +3165,7 @@ void RAMFUNC SniffMifare(uint8_t param) {
                                uint8_t readerdata = (previous_data & 0xF0) | (*data >> 4);
                                if(MillerDecoding(readerdata, (sniffCounter-1)*4)) {
                                        LED_C_INV();
-                                       if (MfSniffLogic(receivedCmd, Uart.len, Uart.parity, Uart.bitCount, TRUE)) break;
+                                       if (MfSniffLogic(receivedCmd, Uart.len, Uart.parity, Uart.bitCount, true)) break;
 
                                        /* And ready to receive another command. */
                                        UartInit(receivedCmd, receivedCmdPar);
@@ -3125,7 +3181,7 @@ void RAMFUNC SniffMifare(uint8_t param) {
                                if(ManchesterDecoding(tagdata, 0, (sniffCounter-1)*4)) {
                                        LED_C_INV();
 
-                                       if (MfSniffLogic(receivedResponse, Demod.len, Demod.parity, Demod.bitCount, FALSE)) break;
+                                       if (MfSniffLogic(receivedResponse, Demod.len, Demod.parity, Demod.bitCount, false)) break;
 
                                        // And ready to receive another response.
                                        DemodReset();
Impressum, Datenschutz