]> git.zerfleddert.de Git - proxmark3-svn/commitdiff
Merge pull request #356 from pwpiwi/low_frequencies
authormarshmellow42 <marshmellow42@users.noreply.github.com>
Mon, 21 Aug 2017 19:29:56 +0000 (15:29 -0400)
committerGitHub <noreply@github.com>
Mon, 21 Aug 2017 19:29:56 +0000 (15:29 -0400)
revert removal of quarter frequency support for hi_read_rx_xcorr.v

24 files changed:
CHANGELOG.md
armsrc/iso14443a.c
armsrc/lfops.c
armsrc/mifarecmd.c
client/Makefile
client/cmddata.c
client/cmdhf14a.c
client/cmdhfmf.c
client/cmdlf.c
client/cmdlfem4x.c
client/cmdlfhid.c
client/cmdlfindala.c
client/cmdlfio.c
client/cmdlfpac.c [new file with mode: 0644]
client/cmdlfpac.h [new file with mode: 0644]
client/cmdlfsecurakey.c
client/mfkey.c
client/mfkey.h
client/mifarehost.c
client/mifarehost.h
client/scripts/formatMifare.lua
common/lfdemod.c
include/mifare.h
tools/mfkey/Makefile

index 045d9b2db926f87f3359ffd8b82564f11fab5c7e..f34b78f03108934f380ef8bdf5246ba07ccf10d8 100644 (file)
@@ -6,10 +6,16 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
 ## [unreleased][unreleased]
 
 ### Changed
+- Improved backdoor detection missbehaving magic s50/1k tag (Fl0-0)
 
 ### Fixed
 
 ### Added
+- Added PAC/Stanley detection to lf search (marshmellow)
+- Added lf pac demod and lf pac read - extracts the raw blocks from a PAC/Stanley tag (marshmellow)
+- Added hf mf c* commands compatibity for 4k and gen1b backdoor (Fl0-0)
+- Added backdoor detection for gen1b magic s70/4k tag (Fl0-0)
+- Added data fsktonrz, a fsk cleaning/demodulating routine for weak fsk signal. Note: follow this up with a `data rawdemod nr` to finish demoding your signal. (marshmellow)
 - Added lf em 410xbrute, LF EM410x reader bruteforce attack by simulating UIDs from a file (Fl0-0)
 
 ## [3.0.1][2017-06-08]
index d648beee338f293b08c45bc9db62d2bf5f019d75..29b23833cd875065c26a1aa06f9981391941c86f 100644 (file)
@@ -2352,18 +2352,6 @@ void ReaderMifare(bool first_try)
        set_tracing(false);
 }
 
-typedef struct {
-  uint32_t cuid;
-  uint8_t  sector;
-  uint8_t  keytype;
-  uint32_t nonce;
-  uint32_t ar;
-  uint32_t nr;
-  uint32_t nonce2;
-  uint32_t ar2;
-  uint32_t nr2;
-} nonces_t;
-
 /**
   *MIFARE 1K simulate.
   *
@@ -2562,7 +2550,10 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
                                LED_A_ON();
                        }
                }
-               if (cardSTATE == MFEMUL_NOFIELD) continue;
+               if (cardSTATE == MFEMUL_NOFIELD) {
+                       button_pushed = BUTTON_PRESS();
+                       continue;
+               }
 
                //Now, get data
                res = EmGetCmd(receivedCmd, &len, receivedCmd_par);
index 566ba1d40982ce2a2cb2e368383b5dc533787d80..393d05a96b949621b96fb93727d7e09c5c3594c8 100644 (file)
@@ -387,7 +387,8 @@ void SimulateTagLowFrequency(int period, int gap, int ledcontrol)
        int i;
        uint8_t *tab = BigBuf_get_addr();
 
-       FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
+       //note this may destroy the bigbuf so be sure this is called before now...
+       FpgaDownloadAndGo(FPGA_BITSTREAM_LF);  
        FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT);
 
        AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT | GPIO_SSC_CLK;
@@ -401,13 +402,19 @@ void SimulateTagLowFrequency(int period, int gap, int ledcontrol)
        i = 0;
        for(;;) {
                //wait until SSC_CLK goes HIGH
+               int ii = 0;
                while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) {
-                       if(BUTTON_PRESS() || (usb_poll_validate_length() )) {
-                               FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
-                               DbpString("Stopped");
-                               return;
+                       //only check every 1000th time (usb_poll_validate_length on some systems was too slow)
+                       if ( ii == 1000 ) {
+                               if (BUTTON_PRESS() || usb_poll_validate_length() ) {
+                                       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+                                       DbpString("Stopped");
+                                       return;
+                               }
+                               ii=0;
                        }
                        WDT_HIT();
+                       ii++;
                }
                if (ledcontrol)
                        LED_D_ON();
@@ -419,14 +426,20 @@ void SimulateTagLowFrequency(int period, int gap, int ledcontrol)
 
                if (ledcontrol)
                        LED_D_OFF();
+               ii=0;
                //wait until SSC_CLK goes LOW
                while(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK) {
-                       if(BUTTON_PRESS() || (usb_poll_validate_length() )) {
-                               DbpString("Stopped");
-                               FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
-                               return;
+                       //only check every 1000th time (usb_poll_validate_length on some systems was too slow)
+                       if ( ii == 1000 ) { 
+                               if (BUTTON_PRESS() || usb_poll_validate_length() ) {
+                                       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+                                       DbpString("Stopped");
+                                       return;
+                               }
+                               ii=0;
                        }
                        WDT_HIT();
+                       ii++;
                }
 
                i++;
@@ -545,6 +558,9 @@ void CmdHIDsimTAG(int hi, int lo, int ledcontrol)
                DbpString("Tags can only have 44 bits. - USE lf simfsk for larger tags");
                return;
        }
+       // set LF so we don't kill the bigbuf we are setting with simulation data.
+       FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
+
        fc(0,&n);
        // special start of frame marker containing invalid bit sequences
        fc(8,  &n);     fc(8,  &n); // invalid
@@ -595,6 +611,9 @@ void CmdFSKsimTAG(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *BitStream)
        uint8_t clk = arg2 & 0xFF;
        uint8_t invert = (arg2 >> 8) & 1;
 
+       // set LF so we don't kill the bigbuf we are setting with simulation data.
+       FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
+
        for (i=0; i<size; i++){
                if (BitStream[i] == invert){
                        fcAll(fcLow, &n, clk, &modCnt);
@@ -670,6 +689,9 @@ void CmdASKsimTag(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *BitStream)
        uint8_t separator = arg2 & 1;
        uint8_t invert = (arg2 >> 8) & 1;
 
+       // set LF so we don't kill the bigbuf we are setting with simulation data.
+       FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
+
        if (encoding==2){  //biphase
                uint8_t phase=0;
                for (i=0; i<size; i++){
@@ -741,6 +763,9 @@ void CmdPSKsimTag(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *BitStream)
        uint8_t carrier = arg1 & 0xFF;
        uint8_t invert = arg2 & 0xFF;
        uint8_t curPhase = 0;
+       // set LF so we don't kill the bigbuf we are setting with simulation data.
+       FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
+
        for (i=0; i<size; i++){
                if (BitStream[i] == curPhase){
                        pskSimBit(carrier, &n, clk, &curPhase, FALSE);
index 6f57c11319c87d185f003a96d55a2f606f7e2f3d..0e9c36725ec4ad24d2be46e2e51342c30b6a7534 100644 (file)
@@ -21,8 +21,8 @@
 #include "crc.h"\r
 \r
 #define AUTHENTICATION_TIMEOUT 848                     // card times out 1ms after wrong authentication (according to NXP documentation)\r
-#define PRE_AUTHENTICATION_LEADTIME 400                // some (non standard) cards need a pause after select before they are ready for first authentication \r
-       \r
+#define PRE_AUTHENTICATION_LEADTIME 400                // some (non standard) cards need a pause after select before they are ready for first authentication\r
+\r
 \r
 // the block number for the ISO14443-4 PCB\r
 static uint8_t pcb_blocknum = 0;\r
@@ -30,7 +30,7 @@ static uint8_t pcb_blocknum = 0;
 static  uint8_t deselect_cmd[] = {0xc2,0xe0,0xb4};\r
 \r
 //-----------------------------------------------------------------------------\r
-// Select, Authenticate, Read a MIFARE tag. \r
+// Select, Authenticate, Read a MIFARE tag.\r
 // read block\r
 //-----------------------------------------------------------------------------\r
 void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)\r
@@ -40,7 +40,7 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
        uint8_t keyType = arg1;\r
        uint64_t ui64Key = 0;\r
        ui64Key = bytes_to_num(datain, 6);\r
-       \r
+\r
        // variables\r
        byte_t isOK = 0;\r
        byte_t dataoutbuf[16];\r
@@ -68,7 +68,7 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
                        if (MF_DBGLEVEL >= 1)   Dbprintf("Auth error");\r
                        break;\r
                };\r
-               \r
+\r
                if(mifare_classic_readblock(pcs, cuid, blockNo, dataoutbuf)) {\r
                        if (MF_DBGLEVEL >= 1)   Dbprintf("Read block error");\r
                        break;\r
@@ -78,14 +78,14 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
                        if (MF_DBGLEVEL >= 1)   Dbprintf("Halt error");\r
                        break;\r
                };\r
-               \r
+\r
                isOK = 1;\r
                break;\r
        }\r
-       \r
+\r
        //  ----------------------------- crypto1 destroy\r
        crypto1_destroy(pcs);\r
-       \r
+\r
        if (MF_DBGLEVEL >= 2)   DbpString("READ BLOCK FINISHED");\r
 \r
        LED_B_ON();\r
@@ -111,7 +111,7 @@ void MifareUC_Auth(uint8_t arg0, uint8_t *keybytes){
                OnError(0);\r
                return;\r
        };\r
-       \r
+\r
        if(!mifare_ultra_auth(keybytes)){\r
                if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Authentication failed");\r
                OnError(1);\r
@@ -168,7 +168,7 @@ void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain)
                        OnError(1);\r
                        return;\r
                }\r
-       }       \r
+       }\r
 \r
        if( mifare_ultra_readblock(blockNo, dataout) ) {\r
                if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Read block error");\r
@@ -188,7 +188,7 @@ void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain)
 }\r
 \r
 //-----------------------------------------------------------------------------\r
-// Select, Authenticate, Read a MIFARE tag. \r
+// Select, Authenticate, Read a MIFARE tag.\r
 // read sector (data = 4 x 16 bytes = 64 bytes, or 16 x 16 bytes = 256 bytes)\r
 //-----------------------------------------------------------------------------\r
 void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)\r
@@ -198,7 +198,7 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
        uint8_t keyType = arg1;\r
        uint64_t ui64Key = 0;\r
        ui64Key = bytes_to_num(datain, 6);\r
-       \r
+\r
        // variables\r
        byte_t isOK = 0;\r
        byte_t dataoutbuf[16 * 16];\r
@@ -222,12 +222,12 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
                if (MF_DBGLEVEL >= 1)   Dbprintf("Can't select card");\r
        }\r
 \r
-       \r
+\r
        if(isOK && mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keyType, ui64Key, AUTH_FIRST)) {\r
                isOK = 0;\r
                if (MF_DBGLEVEL >= 1)   Dbprintf("Auth error");\r
        }\r
-       \r
+\r
        for (uint8_t blockNo = 0; isOK && blockNo < NumBlocksPerSector(sectorNo); blockNo++) {\r
                if(mifare_classic_readblock(pcs, cuid, FirstBlockOfSector(sectorNo) + blockNo, dataoutbuf + 16 * blockNo)) {\r
                        isOK = 0;\r
@@ -235,14 +235,14 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
                        break;\r
                }\r
        }\r
-               \r
+\r
        if(mifare_classic_halt(pcs, cuid)) {\r
                if (MF_DBGLEVEL >= 1)   Dbprintf("Halt error");\r
        }\r
 \r
        //  ----------------------------- crypto1 destroy\r
        crypto1_destroy(pcs);\r
-       \r
+\r
        if (MF_DBGLEVEL >= 2) DbpString("READ SECTOR FINISHED");\r
 \r
        LED_B_ON();\r
@@ -307,7 +307,7 @@ void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain)
 \r
                if (!mifare_ul_ev1_auth(pwd, pack)){\r
                        OnError(1);\r
-                       return;                 \r
+                       return;\r
                }\r
        }\r
 \r
@@ -316,7 +316,7 @@ void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain)
                        Dbprintf("Data exceeds buffer!!");\r
                        break;\r
                }\r
-       \r
+\r
                len = mifare_ultra_readblock(blockNo + i, dataout + 4 * i);\r
 \r
                if (len) {\r
@@ -352,7 +352,7 @@ void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain)
 }\r
 \r
 //-----------------------------------------------------------------------------\r
-// Select, Authenticate, Write a MIFARE tag. \r
+// Select, Authenticate, Write a MIFARE tag.\r
 // read block\r
 //-----------------------------------------------------------------------------\r
 void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)\r
@@ -365,7 +365,7 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
 \r
        ui64Key = bytes_to_num(datain, 6);\r
        memcpy(blockdata, datain + 10, 16);\r
-       \r
+\r
        // variables\r
        byte_t isOK = 0;\r
        uint8_t uid[10];\r
@@ -392,7 +392,7 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
                        if (MF_DBGLEVEL >= 1)   Dbprintf("Auth error");\r
                        break;\r
                };\r
-               \r
+\r
                if(mifare_classic_writeblock(pcs, cuid, blockNo, blockdata)) {\r
                        if (MF_DBGLEVEL >= 1)   Dbprintf("Write block error");\r
                        break;\r
@@ -402,14 +402,14 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
                        if (MF_DBGLEVEL >= 1)   Dbprintf("Halt error");\r
                        break;\r
                };\r
-               \r
+\r
                isOK = 1;\r
                break;\r
        }\r
-       \r
+\r
        //  ----------------------------- crypto1 destroy\r
        crypto1_destroy(pcs);\r
-       \r
+\r
        if (MF_DBGLEVEL >= 2)   DbpString("WRITE BLOCK FINISHED");\r
 \r
        LED_B_ON();\r
@@ -422,7 +422,7 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
        LEDsoff();\r
 }\r
 \r
-/* // Command not needed but left for future testing \r
+/* // Command not needed but left for future testing\r
 void MifareUWriteBlockCompat(uint8_t arg0, uint8_t *datain)\r
 {\r
        uint8_t blockNo = arg0;\r
@@ -476,7 +476,7 @@ void MifareUWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain)
        byte_t blockdata[4] = {0x00};\r
 \r
        memcpy(blockdata, datain,4);\r
-       \r
+\r
        LEDsoff();\r
        LED_A_ON();\r
        iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
@@ -499,7 +499,7 @@ void MifareUWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain)
                        return;\r
                }\r
        }\r
-       \r
+\r
        // UL-EV1 / NTAG authentication\r
        if (usePwd) {\r
                uint8_t pwd[4] = {0x00};\r
@@ -531,12 +531,12 @@ void MifareUWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain)
 }\r
 \r
 void MifareUSetPwd(uint8_t arg0, uint8_t *datain){\r
-       \r
+\r
        uint8_t pwd[16] = {0x00};\r
        byte_t blockdata[4] = {0x00};\r
-       \r
+\r
        memcpy(pwd, datain, 16);\r
-       \r
+\r
        LED_A_ON(); LED_B_OFF(); LED_C_OFF();\r
        iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
 \r
@@ -586,7 +586,7 @@ void MifareUSetPwd(uint8_t arg0, uint8_t *datain){
                if (MF_DBGLEVEL >= 1) Dbprintf("Write block error");\r
                OnError(47);\r
                return;\r
-       };      \r
+       };\r
 \r
        if(mifare_ultra_halt()) {\r
                if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");\r
@@ -610,7 +610,7 @@ int valid_nonce(uint32_t Nt, uint32_t NtEnc, uint32_t Ks1, uint8_t *parity) {
 //-----------------------------------------------------------------------------\r
 // acquire encrypted nonces in order to perform the attack described in\r
 // Carlo Meijer, Roel Verdult, "Ciphertext-only Cryptanalysis on Hardened\r
-// Mifare Classic Cards" in Proceedings of the 22nd ACM SIGSAC Conference on \r
+// Mifare Classic Cards" in Proceedings of the 22nd ACM SIGSAC Conference on\r
 // Computer and Communications Security, 2015\r
 //-----------------------------------------------------------------------------\r
 void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, uint8_t *datain)\r
@@ -628,7 +628,7 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags,
        uint8_t nt_par_enc = 0;\r
        uint8_t buf[USB_CMD_DATA_SIZE];\r
        uint32_t timeout;\r
-       \r
+\r
        uint8_t blockNo = arg0 & 0xff;\r
        uint8_t keyType = (arg0 >> 8) & 0xff;\r
        uint8_t targetBlockNo = arg1 & 0xff;\r
@@ -637,7 +637,7 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags,
        bool initialize = flags & 0x0001;\r
        bool slow = flags & 0x0002;\r
        bool field_off = flags & 0x0004;\r
-       \r
+\r
        LED_A_ON();\r
        LED_C_OFF();\r
 \r
@@ -646,9 +646,9 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags,
                clear_trace();\r
                set_tracing(true);\r
        }\r
-       \r
+\r
        LED_C_ON();\r
-       \r
+\r
        uint16_t num_nonces = 0;\r
        bool have_uid = false;\r
        for (uint16_t i = 0; i <= USB_CMD_DATA_SIZE - 9; ) {\r
@@ -661,7 +661,7 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags,
                }\r
 \r
                if (!have_uid) { // need a full select cycle to get the uid first\r
-                       iso14a_card_select_t card_info;         \r
+                       iso14a_card_select_t card_info;\r
                        if(!iso14443a_select_card(uid, &card_info, &cuid, true, 0)) {\r
                                if (MF_DBGLEVEL >= 1)   Dbprintf("AcquireNonces: Can't select card (ALL)");\r
                                continue;\r
@@ -672,14 +672,14 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags,
                                case 10: cascade_levels = 3; break;\r
                                default: break;\r
                        }\r
-                       have_uid = true;        \r
+                       have_uid = true;\r
                } else { // no need for anticollision. We can directly select the card\r
                        if(!iso14443a_select_card(uid, NULL, NULL, false, cascade_levels)) {\r
                                if (MF_DBGLEVEL >= 1)   Dbprintf("AcquireNonces: Can't select card (UID)");\r
                                continue;\r
                        }\r
                }\r
-               \r
+\r
                if (slow) {\r
                        timeout = GetCountSspClk() + PRE_AUTHENTICATION_LEADTIME;\r
                        while(GetCountSspClk() < timeout);\r
@@ -697,12 +697,12 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags,
                        if (MF_DBGLEVEL >= 1)   Dbprintf("AcquireNonces: Auth2 error len=%d", len);\r
                        continue;\r
                }\r
-       \r
+\r
                // send a dummy byte as reader response in order to trigger the cards authentication timeout\r
                uint8_t dummy_answer = 0;\r
                ReaderTransmit(&dummy_answer, 1, NULL);\r
                timeout = GetCountSspClk() + AUTHENTICATION_TIMEOUT;\r
-               \r
+\r
                num_nonces++;\r
                if (num_nonces % 2) {\r
                        memcpy(buf+i, receivedAnswer, 4);\r
@@ -716,13 +716,13 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags,
 \r
                // wait for the card to become ready again\r
                while(GetCountSspClk() < timeout);\r
-       \r
+\r
        }\r
 \r
        LED_C_OFF();\r
-       \r
+\r
        crypto1_destroy(pcs);\r
-       \r
+\r
        LED_B_ON();\r
        cmd_send(CMD_ACK, isOK, cuid, num_nonces, buf, sizeof(buf));\r
        LED_B_OFF();\r
@@ -737,8 +737,8 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags,
 \r
 \r
 //-----------------------------------------------------------------------------\r
-// MIFARE nested authentication. \r
-// \r
+// MIFARE nested authentication.\r
+//\r
 //-----------------------------------------------------------------------------\r
 void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *datain)\r
 {\r
@@ -750,7 +750,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
        uint64_t ui64Key = 0;\r
 \r
        ui64Key = bytes_to_num(datain, 6);\r
-       \r
+\r
        // variables\r
        uint16_t rtr, i, j, len;\r
        uint16_t davg;\r
@@ -759,7 +759,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
        uint32_t cuid, nt1, nt2, nttmp, nttest, ks1;\r
        uint8_t par[1];\r
        uint32_t target_nt[2], target_ks[2];\r
-       \r
+\r
        uint8_t par_array[4];\r
        uint16_t ncount = 0;\r
        struct Crypto1State mpcs = {0, 0};\r
@@ -779,7 +779,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
 \r
        if (calibrate) clear_trace();\r
        set_tracing(true);\r
-       \r
+\r
        // statistics on nonce distance\r
        int16_t isOK = 0;\r
        #define NESTED_MAX_TRIES 12\r
@@ -791,7 +791,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
                davg = dmax = 0;\r
                dmin = 2000;\r
                delta_time = 0;\r
-               \r
+\r
                for (rtr = 0; rtr < 17; rtr++) {\r
 \r
                        // Test if the action was cancelled\r
@@ -856,17 +856,17 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
                }\r
 \r
                davg = (davg + (rtr - 1)/2) / (rtr - 1);\r
-               \r
+\r
                if (MF_DBGLEVEL >= 3) Dbprintf("rtr=%d isOK=%d min=%d max=%d avg=%d, delta_time=%d", rtr, isOK, dmin, dmax, davg, delta_time);\r
 \r
                dmin = davg - 2;\r
                dmax = davg + 2;\r
-               \r
+\r
                LED_B_OFF();\r
-       \r
+\r
        }\r
-       //  -------------------------------------------------------------------------------------------------   \r
-       \r
+       //  -------------------------------------------------------------------------------------------------\r
+\r
        LED_C_ON();\r
 \r
        //  get crypted nonces for target sector\r
@@ -874,7 +874,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
 \r
                target_nt[i] = 0;\r
                while(target_nt[i] == 0) { // continue until we have an unambiguous nonce\r
-               \r
+\r
                        // prepare next select. No need to power down the card.\r
                        if(mifare_classic_halt(pcs, cuid)) {\r
                                if (MF_DBGLEVEL >= 1)   Dbprintf("Nested: Halt error");\r
@@ -885,7 +885,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
                                if (MF_DBGLEVEL >= 1)   Dbprintf("Nested: Can't select card");\r
                                continue;\r
                        };\r
-               \r
+\r
                        auth1_time = 0;\r
                        if(mifare_classic_authex(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST, &nt1, &auth1_time)) {\r
                                if (MF_DBGLEVEL >= 1)   Dbprintf("Nested: Auth1 error");\r
@@ -899,15 +899,15 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
                                if (MF_DBGLEVEL >= 1)   Dbprintf("Nested: Auth2 error len=%d", len);\r
                                continue;\r
                        };\r
-               \r
-                       nt2 = bytes_to_num(receivedAnswer, 4);          \r
+\r
+                       nt2 = bytes_to_num(receivedAnswer, 4);\r
                        if (MF_DBGLEVEL >= 3) Dbprintf("Nonce#%d: Testing nt1=%08x nt2enc=%08x nt2par=%02x", i+1, nt1, nt2, par[0]);\r
-                       \r
+\r
                        // Parity validity check\r
                        for (j = 0; j < 4; j++) {\r
                                par_array[j] = (oddparity8(receivedAnswer[j]) != ((par[0] >> (7-j)) & 0x01));\r
                        }\r
-                       \r
+\r
                        ncount = 0;\r
                        nttest = prng_successor(nt1, dmin - 1);\r
                        for (j = dmin; j < dmax + 1; j++) {\r
@@ -936,17 +936,17 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
        }\r
 \r
        LED_C_OFF();\r
-       \r
+\r
        //  ----------------------------- crypto1 destroy\r
        crypto1_destroy(pcs);\r
-       \r
+\r
        byte_t buf[4 + 4 * 4];\r
        memcpy(buf, &cuid, 4);\r
        memcpy(buf+4, &target_nt[0], 4);\r
        memcpy(buf+8, &target_ks[0], 4);\r
        memcpy(buf+12, &target_nt[1], 4);\r
        memcpy(buf+16, &target_ks[1], 4);\r
-       \r
+\r
        LED_B_ON();\r
        cmd_send(CMD_ACK, isOK, 0, targetBlockNo + (targetKeyType * 0x100), buf, sizeof(buf));\r
        LED_B_OFF();\r
@@ -958,8 +958,8 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
 }\r
 \r
 //-----------------------------------------------------------------------------\r
-// MIFARE check keys. key count up to 85. \r
-// \r
+// MIFARE check keys. key count up to 85.\r
+//\r
 //-----------------------------------------------------------------------------\r
 void MifareChkKeys(uint16_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)\r
 {\r
@@ -968,7 +968,7 @@ void MifareChkKeys(uint16_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
        bool clearTrace = arg1;\r
        uint8_t keyCount = arg2;\r
        uint64_t ui64Key = 0;\r
-       \r
+\r
        bool have_uid = false;\r
        uint8_t cascade_levels = 0;\r
        uint32_t timeout = 0;\r
@@ -979,11 +979,11 @@ void MifareChkKeys(uint16_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
        struct Crypto1State mpcs = {0, 0};\r
        struct Crypto1State *pcs;\r
        pcs = &mpcs;\r
-       \r
+\r
        // clear debug level\r
-       int OLD_MF_DBGLEVEL = MF_DBGLEVEL;      \r
+       int OLD_MF_DBGLEVEL = MF_DBGLEVEL;\r
        MF_DBGLEVEL = MF_DBG_NONE;\r
-       \r
+\r
        LED_A_ON();\r
        LED_B_OFF();\r
        LED_C_OFF();\r
@@ -999,7 +999,7 @@ void MifareChkKeys(uint16_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
 \r
                // Iceman: use piwi's faster nonce collecting part in hardnested.\r
                if (!have_uid) { // need a full select cycle to get the uid first\r
-                       iso14a_card_select_t card_info;         \r
+                       iso14a_card_select_t card_info;\r
                        if(!iso14443a_select_card(uid, &card_info, &cuid, true, 0)) {\r
                                if (OLD_MF_DBGLEVEL >= 1)       Dbprintf("ChkKeys: Can't select card");\r
                                --i; // try same key once again\r
@@ -1011,7 +1011,7 @@ void MifareChkKeys(uint16_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
                                case 10: cascade_levels = 3; break;\r
                                default: break;\r
                        }\r
-                       have_uid = true;        \r
+                       have_uid = true;\r
                } else { // no need for anticollision. We can directly select the card\r
                        if(!iso14443a_select_card(uid, NULL, NULL, false, cascade_levels)) {\r
                                if (OLD_MF_DBGLEVEL >= 1)       Dbprintf("ChkKeys: Can't select card (UID)");\r
@@ -1025,16 +1025,16 @@ void MifareChkKeys(uint16_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
                        uint8_t dummy_answer = 0;\r
                        ReaderTransmit(&dummy_answer, 1, NULL);\r
                        timeout = GetCountSspClk() + AUTHENTICATION_TIMEOUT;\r
-                       \r
+\r
                        // wait for the card to become ready again\r
                        while(GetCountSspClk() < timeout);\r
                        continue;\r
                }\r
-               \r
+\r
                isOK = 1;\r
                break;\r
        }\r
-       \r
+\r
        LED_B_ON();\r
     cmd_send(CMD_ACK,isOK,0,0,datain + i * 6,6);\r
        LED_B_OFF();\r
@@ -1043,12 +1043,12 @@ void MifareChkKeys(uint16_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
        LEDsoff();\r
 \r
        // restore debug level\r
-       MF_DBGLEVEL = OLD_MF_DBGLEVEL;  \r
+       MF_DBGLEVEL = OLD_MF_DBGLEVEL;\r
 }\r
 \r
 //-----------------------------------------------------------------------------\r
 // MIFARE commands set debug level\r
-// \r
+//\r
 //-----------------------------------------------------------------------------\r
 void MifareSetDbgLvl(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){\r
        MF_DBGLEVEL = arg0;\r
@@ -1057,7 +1057,7 @@ void MifareSetDbgLvl(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
 \r
 //-----------------------------------------------------------------------------\r
 // Work with emulator memory\r
-// \r
+//\r
 // Note: we call FpgaDownloadAndGo(FPGA_BITSTREAM_HF) here although FPGA is not\r
 // involved in dealing with emulator memory. But if it is called later, it might\r
 // destroy the Emulator Memory.\r
@@ -1085,7 +1085,7 @@ void MifareEMemGet(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain)
 \r
 //-----------------------------------------------------------------------------\r
 // Load a card into the emulator memory\r
-// \r
+//\r
 //-----------------------------------------------------------------------------\r
 void MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){\r
        uint8_t numSectors = arg0;\r
@@ -1105,17 +1105,17 @@ void MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
        LED_B_OFF();\r
        LED_C_OFF();\r
        iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
-       \r
+\r
        clear_trace();\r
        set_tracing(false);\r
-       \r
+\r
        bool isOK = true;\r
 \r
        if(!iso14443a_select_card(uid, NULL, &cuid, true, 0)) {\r
                isOK = false;\r
                if (MF_DBGLEVEL >= 1)   Dbprintf("Can't select card");\r
        }\r
-               \r
+\r
        for (uint8_t sectorNo = 0; isOK && sectorNo < numSectors; sectorNo++) {\r
                ui64Key = emlGetKey(sectorNo, keyType);\r
                if (sectorNo == 0){\r
@@ -1131,7 +1131,7 @@ void MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
                                break;\r
                        }\r
                }\r
-               \r
+\r
                for (uint8_t blockNo = 0; isOK && blockNo < NumBlocksPerSector(sectorNo); blockNo++) {\r
                        if(isOK && mifare_classic_readblock(pcs, cuid, FirstBlockOfSector(sectorNo) + blockNo, dataoutbuf)) {\r
                                isOK = false;\r
@@ -1160,7 +1160,7 @@ void MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
 \r
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
        LEDsoff();\r
-       \r
+\r
        if (MF_DBGLEVEL >= 2) DbpString("EMUL FILL SECTORS FINISHED");\r
 \r
 }\r
@@ -1168,10 +1168,10 @@ void MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
 \r
 //-----------------------------------------------------------------------------\r
 // Work with "magic Chinese" card (email him: ouyangweidaxian@live.cn)\r
-// \r
+//\r
 //-----------------------------------------------------------------------------\r
 void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){\r
-  \r
+\r
   // params\r
        uint8_t needWipe = arg0;\r
        // bit 0 - need get UID\r
@@ -1179,20 +1179,21 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
        // bit 2 - need HALT after sequence\r
        // bit 3 - need init FPGA and field before sequence\r
        // bit 4 - need reset FPGA and LED\r
+       // bit 6 - gen1b backdoor type\r
        uint8_t workFlags = arg1;\r
        uint8_t blockNo = arg2;\r
-       \r
+\r
        // card commands\r
-       uint8_t wupC1[]       = { 0x40 }; \r
-       uint8_t wupC2[]       = { 0x43 }; \r
-       uint8_t wipeC[]       = { 0x41 }; \r
-       \r
+       uint8_t wupC1[]       = { 0x40 };\r
+       uint8_t wupC2[]       = { 0x43 };\r
+       uint8_t wipeC[]       = { 0x41 };\r
+\r
        // variables\r
        byte_t isOK = 0;\r
        uint8_t uid[10] = {0x00};\r
        uint8_t d_block[18] = {0x00};\r
        uint32_t cuid;\r
-       \r
+\r
        uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];\r
        uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];\r
 \r
@@ -1202,7 +1203,7 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
                LED_B_OFF();\r
                LED_C_OFF();\r
                iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
-       \r
+\r
                clear_trace();\r
                set_tracing(true);\r
        }\r
@@ -1214,16 +1215,18 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
                        if(!iso14443a_select_card(uid, NULL, &cuid, true, 0)) {\r
                                if (MF_DBGLEVEL >= 1)   Dbprintf("Can't select card");\r
                                break;\r
-                       };\r
+                               };\r
 \r
-                       if(mifare_classic_halt(NULL, cuid)) {\r
-                               if (MF_DBGLEVEL >= 1)   Dbprintf("Halt error");\r
-                               break;\r
-                       };\r
+                               if(mifare_classic_halt(NULL, cuid)) {\r
+                                       if (MF_DBGLEVEL > 2)    Dbprintf("Halt error");\r
+                                       // Continue, some magic tags misbehavies and send an answer to it.\r
+          // break;\r
+                               };\r
                };\r
-       \r
+\r
                // reset chip\r
-               if (needWipe){\r
+               // Wipe command don't work with gen1b\r
+               if (needWipe && !(workFlags & 0x40)){\r
                        ReaderTransmitBitsPar(wupC1,7,0, NULL);\r
                        if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {\r
                                if (MF_DBGLEVEL >= 1)   Dbprintf("wupC1 error");\r
@@ -1237,51 +1240,61 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
                        };\r
 \r
                        if(mifare_classic_halt(NULL, cuid)) {\r
-                               if (MF_DBGLEVEL >= 1)   Dbprintf("Halt error");\r
-                               break;\r
+                               if (MF_DBGLEVEL > 2)    Dbprintf("Halt error");\r
+                               // Continue, some magic tags misbehavies and send an answer to it.\r
+                               // break;\r
                        };\r
-               };      \r
+               };\r
 \r
                // write block\r
                if (workFlags & 0x02) {\r
                        ReaderTransmitBitsPar(wupC1,7,0, NULL);\r
-                       if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {\r
-                               if (MF_DBGLEVEL >= 1)   Dbprintf("wupC1 error");\r
-                               break;\r
-                       };\r
 \r
-                       ReaderTransmit(wupC2, sizeof(wupC2), NULL);\r
-                       if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {\r
-                               if (MF_DBGLEVEL >= 1)   Dbprintf("wupC2 error");\r
-                               break;\r
-                       };\r
+                       // gen1b magic tag : do no issue wupC2 and don't expect 0x0a response after SELECT_UID (after getting UID from chip in 'hf mf csetuid' command)\r
+                       if (!(workFlags & 0x40)) {\r
+\r
+                               if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {\r
+                                       if (MF_DBGLEVEL >= 1)   Dbprintf("wupC1 error");\r
+                                       break;\r
+                               };\r
+\r
+                               ReaderTransmit(wupC2, sizeof(wupC2), NULL);\r
+                               if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {\r
+                                       if (MF_DBGLEVEL >= 1)   Dbprintf("wupC2 error");\r
+                                       break;\r
+                               };\r
+                       }\r
                }\r
 \r
                if ((mifare_sendcmd_short(NULL, 0, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 1) || (receivedAnswer[0] != 0x0a)) {\r
                        if (MF_DBGLEVEL >= 1)   Dbprintf("write block send command error");\r
                        break;\r
                };\r
-       \r
+\r
                memcpy(d_block, datain, 16);\r
                AppendCrc14443a(d_block, 16);\r
-       \r
+\r
                ReaderTransmit(d_block, sizeof(d_block), NULL);\r
                if ((ReaderReceive(receivedAnswer, receivedAnswerPar) != 1) || (receivedAnswer[0] != 0x0a)) {\r
                        if (MF_DBGLEVEL >= 1)   Dbprintf("write block send data error");\r
                        break;\r
-               };      \r
-       \r
+               };\r
+\r
                if (workFlags & 0x04) {\r
-                       if (mifare_classic_halt(NULL, cuid)) {\r
-                               if (MF_DBGLEVEL >= 1)   Dbprintf("Halt error");\r
-                               break;\r
-                       };\r
+                       // do no issue halt command for gen1b magic tag (#db# halt error. response len: 1)\r
+                       if (!(workFlags & 0x40)) {\r
+                               if (mifare_classic_halt(NULL, cuid)) {\r
+                                       if (MF_DBGLEVEL > 2)    Dbprintf("Halt error");\r
+                                       // Continue, some magic tags misbehavies and send an answer to it.\r
+                                       // break;\r
+                               }\r
+                       }\r
                }\r
-               \r
+\r
                isOK = 1;\r
                break;\r
        }\r
-       \r
+\r
        LED_B_ON();\r
        cmd_send(CMD_ACK,isOK,0,0,uid,4);\r
        LED_B_OFF();\r
@@ -1294,28 +1307,29 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
 \r
 \r
 void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){\r
-  \r
-  // params\r
+\r
+       // params\r
        // bit 1 - need wupC\r
        // bit 2 - need HALT after sequence\r
        // bit 3 - need init FPGA and field before sequence\r
        // bit 4 - need reset FPGA and LED\r
        // bit 5 - need to set datain instead of issuing USB reply (called via ARM for StandAloneMode14a)\r
+       // bit 6 - gen1b backdoor type\r
        uint8_t workFlags = arg0;\r
        uint8_t blockNo = arg2;\r
-       \r
+\r
        // card commands\r
-       uint8_t wupC1[]       = { 0x40 }; \r
-       uint8_t wupC2[]       = { 0x43 }; \r
-       \r
+       uint8_t wupC1[]       = { 0x40 };\r
+       uint8_t wupC2[]       = { 0x43 };\r
+\r
        // variables\r
        byte_t isOK = 0;\r
        uint8_t data[18] = {0x00};\r
        uint32_t cuid = 0;\r
-       \r
+\r
        uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];\r
        uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];\r
-       \r
+\r
        if (workFlags & 0x08) {\r
                LED_A_ON();\r
                LED_B_OFF();\r
@@ -1332,14 +1346,16 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
                        if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {\r
                                if (MF_DBGLEVEL >= 1)   Dbprintf("wupC1 error");\r
                                break;\r
-                       };\r
-\r
+               };\r
+               // do no issue for gen1b magic tag\r
+               if (!(workFlags & 0x40)) {\r
                        ReaderTransmit(wupC2, sizeof(wupC2), NULL);\r
                        if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {\r
                                if (MF_DBGLEVEL >= 1)   Dbprintf("wupC2 error");\r
                                break;\r
                        };\r
                }\r
+       }\r
 \r
                // read block\r
                if ((mifare_sendcmd_short(NULL, 0, 0x30, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 18)) {\r
@@ -1347,18 +1363,22 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
                        break;\r
                };\r
                memcpy(data, receivedAnswer, 18);\r
-               \r
+\r
                if (workFlags & 0x04) {\r
-                       if (mifare_classic_halt(NULL, cuid)) {\r
-                               if (MF_DBGLEVEL >= 1)   Dbprintf("Halt error");\r
-                               break;\r
-                       };\r
+                       // do no issue halt command for gen1b magic tag (#db# halt error. response len: 1)\r
+                       if (!(workFlags & 0x40)) {\r
+                               if (mifare_classic_halt(NULL, cuid)) {\r
+                                       if (MF_DBGLEVEL > 1)    Dbprintf("Halt error");\r
+                                       // Continue, some magic tags misbehavies and send an answer to it.\r
+                                       //              break;\r
+                               }\r
+                       }\r
                }\r
-               \r
+\r
                isOK = 1;\r
                break;\r
        }\r
-       \r
+\r
        LED_B_ON();\r
        if (workFlags & 0x20) {\r
                if (isOK)\r
@@ -1375,30 +1395,29 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
 }\r
 \r
 void MifareCIdent(){\r
-  \r
+\r
        // card commands\r
-       uint8_t wupC1[]       = { 0x40 }; \r
-       uint8_t wupC2[]       = { 0x43 }; \r
-       \r
+       uint8_t wupC1[]       = { 0x40 };\r
+       uint8_t wupC2[]       = { 0x43 };\r
+\r
        // variables\r
-       byte_t isOK = 1;\r
-       \r
+       byte_t isOK = 0;\r
+\r
        uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];\r
        uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];\r
 \r
        ReaderTransmitBitsPar(wupC1,7,0, NULL);\r
-       if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {\r
-               isOK = 0;\r
-       };\r
+       if(ReaderReceive(receivedAnswer, receivedAnswerPar) && (receivedAnswer[0] == 0x0a)) {\r
+               isOK = 2;\r
 \r
-       ReaderTransmit(wupC2, sizeof(wupC2), NULL);\r
-       if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {\r
-               isOK = 0;\r
+               ReaderTransmit(wupC2, sizeof(wupC2), NULL);\r
+               if(ReaderReceive(receivedAnswer, receivedAnswerPar) && (receivedAnswer[0] == 0x0a)) {\r
+                       isOK = 1;\r
+               };\r
        };\r
 \r
-       if (mifare_classic_halt(NULL, 0)) {\r
-               isOK = 0;\r
-       };\r
+       // From iceman1001: removed the if,  since some magic tags misbehavies and send an answer to it.\r
+       mifare_classic_halt(NULL, 0);\r
 \r
        cmd_send(CMD_ACK,isOK,0,0,0,0);\r
 }\r
@@ -1412,7 +1431,7 @@ void Mifare_DES_Auth1(uint8_t arg0, uint8_t *datain){
        byte_t dataout[11] = {0x00};\r
        uint8_t uid[10] = {0x00};\r
        uint32_t cuid;\r
-    \r
+\r
        iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
        clear_trace();\r
 \r
@@ -1439,13 +1458,13 @@ void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain){
        uint8_t key[16] = {0x00};\r
        byte_t isOK = 0;\r
        byte_t dataout[12] = {0x00};\r
-    \r
+\r
        memcpy(key, datain, 16);\r
-       \r
+\r
        isOK = mifare_desfire_des_auth2(cuid, key, dataout);\r
-       \r
+\r
        if( isOK) {\r
-               if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("Authentication part2: Failed");  \r
+               if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("Authentication part2: Failed");\r
                OnError(4);\r
                return;\r
        }\r
index d05bdc447ad87a6572b76dc691e506903986220b..fb6520a94f98f089af7f6f301a2eb17680393701 100644 (file)
@@ -140,6 +140,7 @@ CMDSRCS =   crapto1/crapto1.c\
                        cmdlfti.c \
                        cmdlfviking.c\
                        cmdlfvisa2000.c\
+                       cmdlfpac.c\
                        cmdparser.c \
                        cmdmain.c \
                        scripting.c\
@@ -161,7 +162,7 @@ cpu_arch = $(shell uname -m)
 ifneq ($(findstring 86, $(cpu_arch)), )
        MULTIARCHSRCS = hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c
 endif
-ifneq ($(findstring 64, $(cpu_arch)), )
+ifneq ($(findstring amd64, $(cpu_arch)), )
        MULTIARCHSRCS = hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c
 endif
 ifeq ($(MULTIARCHSRCS), )
index c12c2ce6d58cd9341740a215f81a67b468c73744..1f548284826fb65b8fd430742ce09b5405a3305b 100644 (file)
@@ -1234,6 +1234,7 @@ int getSamples(int n, bool silent)
        }
 
        setClockGrid(0,0);
+       DemodBufferLen = 0;
        RepaintGraphWindow();
        return 0;
 }
@@ -1338,6 +1339,7 @@ int CmdLoad(const char *Cmd)
        fclose(f);
        PrintAndLog("loaded %d samples", GraphTraceLen);
        setClockGrid(0,0);
+       DemodBufferLen = 0;
        RepaintGraphWindow();
        return 0;
 }
@@ -1395,8 +1397,7 @@ int CmdNorm(const char *Cmd)
 
        if (max != min) {
                for (i = 0; i < GraphTraceLen; ++i) {
-                       GraphBuffer[i] = (GraphBuffer[i] - ((max + min) / 2)) * 256 /
-                               (max - min);
+                       GraphBuffer[i] = ((long)(GraphBuffer[i] - ((max + min) / 2)) * 256) / (max - min);
                                //marshmelow: adjusted *1000 to *256 to make +/- 128 so demod commands still work
                }
        }
@@ -1606,6 +1607,205 @@ int Cmdhex2bin(const char *Cmd)
        return 0;
 }
 
+       /* // example of FSK2 RF/50 Tones
+       static const int LowTone[]  = {
+       1,  1,  1,  1,  1, -1, -1, -1, -1, -1,
+       1,  1,  1,  1,  1, -1, -1, -1, -1, -1,
+       1,  1,  1,  1,  1, -1, -1, -1, -1, -1,
+       1,  1,  1,  1,  1, -1, -1, -1, -1, -1,
+       1,  1,  1,  1,  1, -1, -1, -1, -1, -1
+       };
+       static const int HighTone[] = {
+       1,  1,  1,  1,  1,     -1, -1, -1, -1, // note one extra 1 to padd due to 50/8 remainder (1/2 the remainder)
+       1,  1,  1,  1,         -1, -1, -1, -1,
+       1,  1,  1,  1,         -1, -1, -1, -1,
+       1,  1,  1,  1,         -1, -1, -1, -1,
+       1,  1,  1,  1,         -1, -1, -1, -1,
+       1,  1,  1,  1,     -1, -1, -1, -1, -1, // note one extra -1 to padd due to 50/8 remainder
+       };
+       */
+void GetHiLoTone(int *LowTone, int *HighTone, int clk, int LowToneFC, int HighToneFC) {
+       int i,j=0;
+       int Left_Modifier = ((clk % LowToneFC) % 2) + ((clk % LowToneFC)/2);
+       int Right_Modifier = (clk % LowToneFC) / 2;
+       //int HighToneMod = clk mod HighToneFC;
+       int LeftHalfFCCnt = (LowToneFC % 2) + (LowToneFC/2); //truncate
+       int FCs_per_clk = clk/LowToneFC;
+       
+       // need to correctly split up the clock to field clocks.
+       // First attempt uses modifiers on each end to make up for when FCs don't evenly divide into Clk
+
+       // start with LowTone
+       // set extra 1 modifiers to make up for when FC doesn't divide evenly into Clk
+       for (i = 0; i < Left_Modifier; i++) {
+               LowTone[i] = 1;
+       }
+
+       // loop # of field clocks inside the main clock
+       for (i = 0; i < (FCs_per_clk); i++) {
+               // loop # of samples per field clock
+               for (j = 0; j < LowToneFC; j++) {
+                       LowTone[(i*LowToneFC)+Left_Modifier+j] = ( j < LeftHalfFCCnt ) ? 1 : -1;
+               }
+       }
+
+       int k;
+       // add last -1 modifiers
+       for (k = 0; k < Right_Modifier; k++) {
+               LowTone[((i-1)*LowToneFC)+Left_Modifier+j+k] = -1;
+       }
+
+       // now do hightone
+       Left_Modifier = ((clk % HighToneFC) % 2) + ((clk % HighToneFC)/2);
+       Right_Modifier = (clk % HighToneFC) / 2;
+       LeftHalfFCCnt = (HighToneFC % 2) + (HighToneFC/2); //truncate
+       FCs_per_clk = clk/HighToneFC;
+
+       for (i = 0; i < Left_Modifier; i++) {
+               HighTone[i] = 1;
+       }
+
+       // loop # of field clocks inside the main clock
+       for (i = 0; i < (FCs_per_clk); i++) {
+               // loop # of samples per field clock
+               for (j = 0; j < HighToneFC; j++) {
+                       HighTone[(i*HighToneFC)+Left_Modifier+j] = ( j < LeftHalfFCCnt ) ? 1 : -1;
+               }
+       }
+
+       // add last -1 modifiers
+       for (k = 0; k < Right_Modifier; k++) {
+               PrintAndLog("(i-1)*HighToneFC+lm+j+k %i",((i-1)*HighToneFC)+Left_Modifier+j+k);
+               HighTone[((i-1)*HighToneFC)+Left_Modifier+j+k] = -1;
+       }
+       if (g_debugMode == 2) {
+               for ( i = 0; i < clk; i++) {
+                       PrintAndLog("Low: %i,  High: %i",LowTone[i],HighTone[i]);
+               }
+       }
+}
+
+//old CmdFSKdemod adapted by marshmellow 
+//converts FSK to clear NRZ style wave.  (or demodulates)
+int FSKToNRZ(int *data, int *dataLen, int clk, int LowToneFC, int HighToneFC) {
+       uint8_t ans=0;
+       if (clk == 0 || LowToneFC == 0 || HighToneFC == 0) {
+               int firstClockEdge=0;
+               ans = fskClocks((uint8_t *) &LowToneFC, (uint8_t *) &HighToneFC, (uint8_t *) &clk, false, &firstClockEdge);
+               if (g_debugMode > 1) {
+                       PrintAndLog     ("DEBUG FSKtoNRZ: detected clocks: fc_low %i, fc_high %i, clk %i, firstClockEdge %i, ans %u", LowToneFC, HighToneFC, clk, firstClockEdge, ans);
+               }
+       }
+       // currently only know fsk modulations with field clocks < 10 samples and > 4 samples. filter out to remove false positives (and possibly destroying ask/psk modulated waves...)
+       if (ans == 0 || clk == 0 || LowToneFC == 0 || HighToneFC == 0 || LowToneFC > 10 || HighToneFC   < 4) {
+               if (g_debugMode > 1) {
+                       PrintAndLog     ("DEBUG FSKtoNRZ: no fsk clocks found");
+               }
+               return 0;
+       }
+       int LowTone[clk];
+       int HighTone[clk];
+       GetHiLoTone(LowTone, HighTone, clk, LowToneFC, HighToneFC);
+       
+       int i, j;
+
+       // loop through ([all samples] - clk)
+       for (i = 0; i < *dataLen - clk; ++i) {
+               int lowSum = 0, highSum = 0;
+
+               // sum all samples together starting from this sample for [clk] samples for each tone (multiply tone value with sample data)
+               for (j = 0; j < clk; ++j) {
+                       lowSum += LowTone[j] * data[i+j];
+                       highSum += HighTone[j] * data[i + j];
+               }
+               // get abs( [average sample value per clk] * 100 )  (or a rolling average of sorts)
+               lowSum = abs(100 * lowSum / clk);
+               highSum = abs(100 * highSum / clk);
+               // save these back to buffer for later use
+               data[i] = (highSum << 16) | lowSum;
+       }
+
+       // now we have the abs( [average sample value per clk] * 100 ) for each tone
+       //   loop through again [all samples] - clk - 16  
+       //                  note why 16???  is 16 the largest FC? changed to LowToneFC as that should be the > fc
+       for(i = 0; i < *dataLen - clk - LowToneFC; ++i) {
+               int lowTot = 0, highTot = 0;
+
+               // sum a field clock width of abs( [average sample values per clk] * 100) for each tone
+               for (j = 0; j < LowToneFC; ++j) {  //10 for fsk2
+                 lowTot += (data[i + j] & 0xffff);
+               }
+               for (j = 0; j < HighToneFC; j++) {  //8 for fsk2
+                 highTot += (data[i + j] >> 16);
+               }
+
+               // subtract the sum of lowTone averages by the sum of highTone averages as it 
+               //   and write back the new graph value 
+               data[i] = lowTot - highTot;
+       }
+       // update dataLen to what we put back to the data sample buffer
+       *dataLen -= (clk + LowToneFC);
+       return 0;
+}
+
+int usage_data_fsktonrz() {
+               PrintAndLog("Usage: data fsktonrz c <clock> l <fc_low> f <fc_high>");
+               PrintAndLog("Options:        ");
+               PrintAndLog("       h            This help");
+               PrintAndLog("       c <clock>    enter the a clock (omit to autodetect)");
+               PrintAndLog("       l <fc_low>   enter a field clock (omit to autodetect)");
+               PrintAndLog("       f <fc_high>  enter a field clock (omit to autodetect)");
+               return 0;       
+}
+
+int CmdFSKToNRZ(const char *Cmd) {
+       // take clk, fc_low, fc_high 
+       //   blank = auto;
+       bool errors = false;
+       int clk = 0;
+       char cmdp = 0;
+       int fc_low = 10, fc_high = 8;
+       while(param_getchar(Cmd, cmdp) != 0x00)
+       {
+               switch(param_getchar(Cmd, cmdp))
+               {
+               case 'h':
+               case 'H':
+                       return usage_data_fsktonrz();
+               case 'C':
+               case 'c':
+                       clk = param_get32ex(Cmd, cmdp+1, 0, 10);
+                       cmdp += 2;
+                       break;
+               case 'F':
+               case 'f':
+                       fc_high = param_get32ex(Cmd, cmdp+1, 0, 10);
+                       cmdp += 2;
+                       break;
+               case 'L':
+               case 'l':
+                       fc_low = param_get32ex(Cmd, cmdp+1, 0, 10);
+                       cmdp += 2;
+                       break;
+               default:
+                       PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
+                       errors = true;
+                       break;
+               }
+               if(errors) break;
+       }
+       //Validations
+       if(errors) return usage_data_fsktonrz();
+
+       setClockGrid(0,0);
+       DemodBufferLen = 0;
+       int ans = FSKToNRZ(GraphBuffer, &GraphTraceLen, clk, fc_low, fc_high);
+       CmdNorm("");
+       RepaintGraphWindow();
+       return ans;
+}
+
+
 static command_t CommandTable[] =
 {
        {"help",            CmdHelp,            1, "This help"},
@@ -1617,6 +1817,7 @@ static command_t CommandTable[] =
        {"buffclear",       CmdBuffClear,       1, "Clear sample buffer and graph window"},
        {"dec",             CmdDec,             1, "Decimate samples"},
        {"detectclock",     CmdDetectClockRate, 1, "[modulation] Detect clock rate of wave in GraphBuffer (options: 'a','f','n','p' for ask, fsk, nrz, psk respectively)"},
+       {"fsktonrz",        CmdFSKToNRZ,        1, "Convert fsk2 to nrz wave for alternate fsk demodulating (for weak fsk)"},
        {"getbitstream",    CmdGetBitStream,    1, "Convert GraphBuffer's >=1 values to 1 and <1 to 0"},
        {"grid",            CmdGrid,            1, "<x> <y> -- overlay grid on graph window, use zero value to turn off either"},
        {"hexsamples",      CmdHexsamples,      0, "<bytes> [<offset>] -- Dump big buffer as hex bytes"},
index bab3591ebc53e7f300700c85468223e04d3e3a0f..b75215a0d41ef1b4f00a30e12a4ddf098dbbfc5e 100644 (file)
@@ -411,8 +411,13 @@ int CmdHF14AReader(const char *Cmd)
        c.arg[2] = 0;   
        SendCommand(&c);
        WaitForResponse(CMD_ACK,&resp);
-       uint8_t isOK  = resp.arg[0] & 0xff;
-       PrintAndLog("Answers to chinese magic backdoor commands: %s", (isOK ? "YES" : "NO") );
+       
+       uint8_t isGeneration = resp.arg[0] & 0xff;
+       switch( isGeneration ){
+               case 1: PrintAndLog("Answers to chinese magic backdoor commands (GEN 1a): YES"); break;
+               case 2: PrintAndLog("Answers to chinese magic backdoor commands (GEN 1b): YES"); break;
+               default: PrintAndLog("Answers to chinese magic backdoor commands: NO"); break;
+       }
        
        // disconnect
        c.cmd = CMD_READER_ISO_14443a;
index d909cd8c8f9e1fa690ad93871955c0381d53e5a4..90ebc27b80ef508f7890309801ab3f1f54985224 100644 (file)
@@ -28,7 +28,6 @@
 \r
 #define NESTED_SECTOR_RETRY     10                     // how often we try mfested() until we give up\r
 \r
-\r
 static int CmdHelp(const char *Cmd);\r
 \r
 int CmdHF14AMifare(const char *Cmd)\r
@@ -45,7 +44,7 @@ int CmdHF14AMifare(const char *Cmd)
                case -5 : PrintAndLog("Aborted via keyboard.");  return 1;\r
                default : PrintAndLog("Found valid key:%012" PRIx64 "\n", key);\r
        }\r
-       \r
+\r
        PrintAndLog("");\r
        return 0;\r
 }\r
@@ -57,14 +56,14 @@ int CmdHF14AMfWrBl(const char *Cmd)
        uint8_t keyType = 0;\r
        uint8_t key[6] = {0, 0, 0, 0, 0, 0};\r
        uint8_t bldata[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};\r
-       \r
+\r
        char cmdp       = 0x00;\r
 \r
        if (strlen(Cmd)<3) {\r
                PrintAndLog("Usage:  hf mf wrbl    <block number> <key A/B> <key (12 hex symbols)> <block data (32 hex symbols)>");\r
                PrintAndLog("        sample: hf mf wrbl 0 A FFFFFFFFFFFF 000102030405060708090A0B0C0D0E0F");\r
                return 0;\r
-       }       \r
+       }\r
 \r
        blockNo = param_get8(Cmd, 0);\r
        cmdp = param_getchar(Cmd, 1);\r
@@ -83,7 +82,7 @@ int CmdHF14AMfWrBl(const char *Cmd)
        }\r
        PrintAndLog("--block no:%d, key type:%c, key:%s", blockNo, keyType?'B':'A', sprint_hex(key, 6));\r
        PrintAndLog("--data: %s", sprint_hex(bldata, 16));\r
-       \r
+\r
   UsbCommand c = {CMD_MIFARE_WRITEBL, {blockNo, keyType, 0}};\r
        memcpy(c.d.asBytes, key, 6);\r
        memcpy(c.d.asBytes + 10, bldata, 16);\r
@@ -105,7 +104,7 @@ int CmdHF14AMfRdBl(const char *Cmd)
        uint8_t blockNo = 0;\r
        uint8_t keyType = 0;\r
        uint8_t key[6] = {0, 0, 0, 0, 0, 0};\r
-       \r
+\r
        char cmdp       = 0x00;\r
 \r
 \r
@@ -113,8 +112,8 @@ int CmdHF14AMfRdBl(const char *Cmd)
                PrintAndLog("Usage:  hf mf rdbl    <block number> <key A/B> <key (12 hex symbols)>");\r
                PrintAndLog("        sample: hf mf rdbl 0 A FFFFFFFFFFFF ");\r
                return 0;\r
-       }       \r
-       \r
+       }\r
+\r
        blockNo = param_get8(Cmd, 0);\r
        cmdp = param_getchar(Cmd, 1);\r
        if (cmdp == 0x00) {\r
@@ -127,7 +126,7 @@ int CmdHF14AMfRdBl(const char *Cmd)
                return 1;\r
        }\r
        PrintAndLog("--block no:%d, key type:%c, key:%s ", blockNo, keyType?'B':'A', sprint_hex(key, 6));\r
-       \r
+\r
   UsbCommand c = {CMD_MIFARE_READBL, {blockNo, keyType, 0}};\r
        memcpy(c.d.asBytes, key, 6);\r
   SendCommand(&c);\r
@@ -162,8 +161,8 @@ int CmdHF14AMfRdSc(const char *Cmd)
                PrintAndLog("Usage:  hf mf rdsc    <sector number> <key A/B> <key (12 hex symbols)>");\r
                PrintAndLog("        sample: hf mf rdsc 0 A FFFFFFFFFFFF ");\r
                return 0;\r
-       }       \r
-       \r
+       }\r
+\r
        sectorNo = param_get8(Cmd, 0);\r
        if (sectorNo > 39) {\r
                PrintAndLog("Sector number must be less than 40");\r
@@ -180,7 +179,7 @@ int CmdHF14AMfRdSc(const char *Cmd)
                return 1;\r
        }\r
        PrintAndLog("--sector no:%d key type:%c key:%s ", sectorNo, keyType?'B':'A', sprint_hex(key, 6));\r
-       \r
+\r
        UsbCommand c = {CMD_MIFARE_READSC, {sectorNo, keyType, 0}};\r
        memcpy(c.d.asBytes, key, 6);\r
        SendCommand(&c);\r
@@ -226,28 +225,28 @@ uint8_t NumBlocksPerSector(uint8_t sectorNo)
 int CmdHF14AMfDump(const char *Cmd)\r
 {\r
        uint8_t sectorNo, blockNo;\r
-       \r
+\r
        uint8_t keyA[40][6];\r
        uint8_t keyB[40][6];\r
        uint8_t rights[40][4];\r
        uint8_t carddata[256][16];\r
        uint8_t numSectors = 16;\r
-       \r
+\r
        FILE *fin;\r
        FILE *fout;\r
-       \r
+\r
        UsbCommand resp;\r
 \r
        char cmdp = param_getchar(Cmd, 0);\r
        switch (cmdp) {\r
                case '0' : numSectors = 5; break;\r
-               case '1' : \r
+               case '1' :\r
                case '\0': numSectors = 16; break;\r
                case '2' : numSectors = 32; break;\r
                case '4' : numSectors = 40; break;\r
                default:   numSectors = 16;\r
-       }       \r
-       \r
+       }\r
+\r
        if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') {\r
                PrintAndLog("Usage:   hf mf dump [card memory]");\r
                PrintAndLog("  [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K");\r
@@ -256,12 +255,12 @@ int CmdHF14AMfDump(const char *Cmd)
                PrintAndLog("         hf mf dump 4");\r
                return 0;\r
        }\r
-       \r
+\r
        if ((fin = fopen("dumpkeys.bin","rb")) == NULL) {\r
                PrintAndLog("Could not find file dumpkeys.bin");\r
                return 1;\r
        }\r
-       \r
+\r
        // Read keys A from file\r
        for (sectorNo=0; sectorNo<numSectors; sectorNo++) {\r
                size_t bytes_read = fread(keyA[sectorNo], 1, 6, fin);\r
@@ -271,7 +270,7 @@ int CmdHF14AMfDump(const char *Cmd)
                        return 2;\r
                }\r
        }\r
-       \r
+\r
        // Read keys B from file\r
        for (sectorNo=0; sectorNo<numSectors; sectorNo++) {\r
                size_t bytes_read = fread(keyB[sectorNo], 1, 6, fin);\r
@@ -281,7 +280,7 @@ int CmdHF14AMfDump(const char *Cmd)
                        return 2;\r
                }\r
        }\r
-       \r
+\r
        fclose(fin);\r
 \r
        PrintAndLog("|-----------------------------------------|");\r
@@ -289,7 +288,7 @@ int CmdHF14AMfDump(const char *Cmd)
        PrintAndLog("|-----------------------------------------|");\r
        uint8_t tries = 0;\r
        for (sectorNo = 0; sectorNo < numSectors; sectorNo++) {\r
-               for (tries = 0; tries < 3; tries++) {           \r
+               for (tries = 0; tries < 3; tries++) {\r
                        UsbCommand c = {CMD_MIFARE_READBL, {FirstBlockOfSector(sectorNo) + NumBlocksPerSector(sectorNo) - 1, 0, 0}};\r
                        memcpy(c.d.asBytes, keyA[sectorNo], 6);\r
                        SendCommand(&c);\r
@@ -315,17 +314,17 @@ int CmdHF14AMfDump(const char *Cmd)
                        }\r
                }\r
        }\r
-       \r
+\r
        PrintAndLog("|-----------------------------------------|");\r
        PrintAndLog("|----- Dumping all blocks to file... -----|");\r
        PrintAndLog("|-----------------------------------------|");\r
-       \r
+\r
        bool isOK = true;\r
        for (sectorNo = 0; isOK && sectorNo < numSectors; sectorNo++) {\r
                for (blockNo = 0; isOK && blockNo < NumBlocksPerSector(sectorNo); blockNo++) {\r
                        bool received = false;\r
-                       for (tries = 0; tries < 3; tries++) {                   \r
-                               if (blockNo == NumBlocksPerSector(sectorNo) - 1) {              // sector trailer. At least the Access Conditions can always be read with key A. \r
+                       for (tries = 0; tries < 3; tries++) {\r
+                               if (blockNo == NumBlocksPerSector(sectorNo) - 1) {              // sector trailer. At least the Access Conditions can always be read with key A.\r
                                        UsbCommand c = {CMD_MIFARE_READBL, {FirstBlockOfSector(sectorNo) + blockNo, 0, 0}};\r
                                        memcpy(c.d.asBytes, keyA[sectorNo], 6);\r
                                        SendCommand(&c);\r
@@ -388,7 +387,7 @@ int CmdHF14AMfDump(const char *Cmd)
        }\r
 \r
        if (isOK) {\r
-               if ((fout = fopen("dumpdata.bin","wb")) == NULL) { \r
+               if ((fout = fopen("dumpdata.bin","wb")) == NULL) {\r
                        PrintAndLog("Could not create file name dumpdata.bin");\r
                        return 1;\r
                }\r
@@ -397,7 +396,7 @@ int CmdHF14AMfDump(const char *Cmd)
                fclose(fout);\r
                PrintAndLog("Dumped %d blocks (%d bytes) to file dumpdata.bin", numblocks, 16*numblocks);\r
        }\r
-               \r
+\r
        return 0;\r
 }\r
 \r
@@ -410,19 +409,19 @@ int CmdHF14AMfRestore(const char *Cmd)
        uint8_t keyA[40][6];\r
        uint8_t keyB[40][6];\r
        uint8_t numSectors;\r
-       \r
+\r
        FILE *fdump;\r
        FILE *fkeys;\r
 \r
        char cmdp = param_getchar(Cmd, 0);\r
        switch (cmdp) {\r
                case '0' : numSectors = 5; break;\r
-               case '1' : \r
+               case '1' :\r
                case '\0': numSectors = 16; break;\r
                case '2' : numSectors = 32; break;\r
                case '4' : numSectors = 40; break;\r
                default:   numSectors = 16;\r
-       }       \r
+       }\r
 \r
        if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') {\r
                PrintAndLog("Usage:   hf mf restore [card memory]");\r
@@ -437,7 +436,7 @@ int CmdHF14AMfRestore(const char *Cmd)
                PrintAndLog("Could not find file dumpkeys.bin");\r
                return 1;\r
        }\r
-       \r
+\r
        for (sectorNo = 0; sectorNo < numSectors; sectorNo++) {\r
                size_t bytes_read = fread(keyA[sectorNo], 1, 6, fkeys);\r
                if (bytes_read != 6) {\r
@@ -461,21 +460,21 @@ int CmdHF14AMfRestore(const char *Cmd)
        if ((fdump = fopen("dumpdata.bin","rb")) == NULL) {\r
                PrintAndLog("Could not find file dumpdata.bin");\r
                return 1;\r
-       }       \r
+       }\r
        PrintAndLog("Restoring dumpdata.bin to card");\r
 \r
        for (sectorNo = 0; sectorNo < numSectors; sectorNo++) {\r
                for(blockNo = 0; blockNo < NumBlocksPerSector(sectorNo); blockNo++) {\r
                        UsbCommand c = {CMD_MIFARE_WRITEBL, {FirstBlockOfSector(sectorNo) + blockNo, keyType, 0}};\r
                        memcpy(c.d.asBytes, key, 6);\r
-                       \r
+\r
                        size_t bytes_read = fread(bldata, 1, 16, fdump);\r
                        if (bytes_read != 16) {\r
                                PrintAndLog("File reading error (dumpdata.bin).");\r
                                fclose(fdump);\r
                                return 2;\r
                        }\r
-                                       \r
+\r
                        if (blockNo == NumBlocksPerSector(sectorNo) - 1) {      // sector trailer\r
                                bldata[0]  = (keyA[sectorNo][0]);\r
                                bldata[1]  = (keyA[sectorNo][1]);\r
@@ -489,10 +488,10 @@ int CmdHF14AMfRestore(const char *Cmd)
                                bldata[13] = (keyB[sectorNo][3]);\r
                                bldata[14] = (keyB[sectorNo][4]);\r
                                bldata[15] = (keyB[sectorNo][5]);\r
-                       }               \r
-                       \r
+                       }\r
+\r
                        PrintAndLog("Writing to block %3d: %s", FirstBlockOfSector(sectorNo) + blockNo, sprint_hex(bldata, 16));\r
-                       \r
+\r
                        memcpy(c.d.asBytes + 10, bldata, 16);\r
                        SendCommand(&c);\r
 \r
@@ -505,7 +504,7 @@ int CmdHF14AMfRestore(const char *Cmd)
                        }\r
                }\r
        }\r
-       \r
+\r
        fclose(fdump);\r
        return 0;\r
 }\r
@@ -530,12 +529,12 @@ int CmdHF14AMfNested(const char *Cmd)
        uint8_t keyBlock[14*6];\r
        uint64_t key64 = 0;\r
        bool transferToEml = false;\r
-       \r
+\r
        bool createDumpFile = false;\r
        FILE *fkeys;\r
        uint8_t standart[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};\r
        uint8_t tempkey[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};\r
-       \r
+\r
        char cmdp, ctmp;\r
 \r
        if (strlen(Cmd)<3) {\r
@@ -552,25 +551,25 @@ int CmdHF14AMfNested(const char *Cmd)
                PrintAndLog("      sample3: hf mf nested 1 0 A FFFFFFFFFFFF d ");\r
                PrintAndLog("      sample4: hf mf nested o 0 A FFFFFFFFFFFF 4 A");\r
                return 0;\r
-       }       \r
-       \r
+       }\r
+\r
        cmdp = param_getchar(Cmd, 0);\r
        blockNo = param_get8(Cmd, 1);\r
        ctmp = param_getchar(Cmd, 2);\r
-       \r
+\r
        if (ctmp != 'a' && ctmp != 'A' && ctmp != 'b' && ctmp != 'B') {\r
                PrintAndLog("Key type must be A or B");\r
                return 1;\r
        }\r
-       \r
-       if (ctmp != 'A' && ctmp != 'a') \r
+\r
+       if (ctmp != 'A' && ctmp != 'a')\r
                keyType = 1;\r
-               \r
+\r
        if (param_gethex(Cmd, 3, key, 12)) {\r
                PrintAndLog("Key must include 12 HEX symbols");\r
                return 1;\r
        }\r
-       \r
+\r
        if (cmdp == 'o' || cmdp == 'O') {\r
                cmdp = 'o';\r
                trgBlockNo = param_get8(Cmd, 4);\r
@@ -579,10 +578,10 @@ int CmdHF14AMfNested(const char *Cmd)
                        PrintAndLog("Target key type must be A or B");\r
                        return 1;\r
                }\r
-               if (ctmp != 'A' && ctmp != 'a') \r
+               if (ctmp != 'A' && ctmp != 'a')\r
                        trgKeyType = 1;\r
        } else {\r
-                               \r
+\r
                switch (cmdp) {\r
                        case '0': SectorsCnt = 05; break;\r
                        case '1': SectorsCnt = 16; break;\r
@@ -595,11 +594,11 @@ int CmdHF14AMfNested(const char *Cmd)
        ctmp = param_getchar(Cmd, 4);\r
        if              (ctmp == 't' || ctmp == 'T') transferToEml = true;\r
        else if (ctmp == 'd' || ctmp == 'D') createDumpFile = true;\r
-       \r
+\r
        ctmp = param_getchar(Cmd, 6);\r
        transferToEml |= (ctmp == 't' || ctmp == 'T');\r
        transferToEml |= (ctmp == 'd' || ctmp == 'D');\r
-       \r
+\r
        if (cmdp == 'o') {\r
                PrintAndLog("--target block no:%3d, target key type:%c ", trgBlockNo, trgKeyType?'B':'A');\r
                int16_t isOK = mfnested(blockNo, keyType, key, trgBlockNo, trgKeyType, keyBlock, true);\r
@@ -625,12 +624,12 @@ int CmdHF14AMfNested(const char *Cmd)
                                        sectortrailer = (trgBlockNo & 0x0f) + 15;\r
                                }\r
                                mfEmlGetMem(keyBlock, sectortrailer, 1);\r
-               \r
+\r
                                if (!trgKeyType)\r
                                        num_to_bytes(key64, 6, keyBlock);\r
                                else\r
                                        num_to_bytes(key64, 6, &keyBlock[10]);\r
-                               mfEmlSetMem(keyBlock, sectortrailer, 1);                \r
+                               mfEmlSetMem(keyBlock, sectortrailer, 1);\r
                        }\r
                } else {\r
                        PrintAndLog("No valid key found");\r
@@ -642,7 +641,7 @@ int CmdHF14AMfNested(const char *Cmd)
 \r
                e_sector = calloc(SectorsCnt, sizeof(sector_t));\r
                if (e_sector == NULL) return 1;\r
-               \r
+\r
                //test current key and additional standard keys first\r
                memcpy(keyBlock, key, 6);\r
                num_to_bytes(0xffffffffffff, 6, (uint8_t*)(keyBlock + 1 * 6));\r
@@ -663,23 +662,23 @@ int CmdHF14AMfNested(const char *Cmd)
                for (i = 0; i < SectorsCnt; i++) {\r
                        for (j = 0; j < 2; j++) {\r
                                if (e_sector[i].foundKey[j]) continue;\r
-                               \r
+\r
                                res = mfCheckKeys(FirstBlockOfSector(i), j, true, 6, keyBlock, &key64);\r
-                               \r
+\r
                                if (!res) {\r
                                        e_sector[i].Key[j] = key64;\r
                                        e_sector[i].foundKey[j] = 1;\r
                                }\r
                        }\r
                }\r
-               \r
+\r
                // nested sectors\r
                iterations = 0;\r
                PrintAndLog("nested...");\r
                bool calibrate = true;\r
                for (i = 0; i < NESTED_SECTOR_RETRY; i++) {\r
                        for (uint8_t sectorNo = 0; sectorNo < SectorsCnt; sectorNo++) {\r
-                               for (trgKeyType = 0; trgKeyType < 2; trgKeyType++) { \r
+                               for (trgKeyType = 0; trgKeyType < 2; trgKeyType++) {\r
                                        if (e_sector[sectorNo].foundKey[trgKeyType]) continue;\r
                                        PrintAndLog("-----------------------------------------------");\r
                                        int16_t isOK = mfnested(blockNo, keyType, key, FirstBlockOfSector(sectorNo), trgKeyType, keyBlock, calibrate);\r
@@ -695,7 +694,7 @@ int CmdHF14AMfNested(const char *Cmd)
                                        } else {\r
                                                calibrate = false;\r
                                        }\r
-                                       \r
+\r
                                        iterations++;\r
 \r
                                        key64 = bytes_to_num(keyBlock, 6);\r
@@ -709,7 +708,7 @@ int CmdHF14AMfNested(const char *Cmd)
                }\r
 \r
                printf("Time in nested: %1.3f (%1.3f sec per key)\n\n", ((float)(msclock() - msclock1))/1000.0, ((float)(msclock() - msclock1))/iterations/1000.0);\r
-               \r
+\r
                PrintAndLog("-----------------------------------------------\nIterations count: %d\n\n", iterations);\r
                //print them\r
                PrintAndLog("|---|----------------|---|----------------|---|");\r
@@ -720,7 +719,7 @@ int CmdHF14AMfNested(const char *Cmd)
                                e_sector[i].Key[0], e_sector[i].foundKey[0], e_sector[i].Key[1], e_sector[i].foundKey[1]);\r
                }\r
                PrintAndLog("|---|----------------|---|----------------|---|");\r
-               \r
+\r
                // transfer them to the emulator\r
                if (transferToEml) {\r
                        for (i = 0; i < SectorsCnt; i++) {\r
@@ -730,12 +729,12 @@ int CmdHF14AMfNested(const char *Cmd)
                                if (e_sector[i].foundKey[1])\r
                                        num_to_bytes(e_sector[i].Key[1], 6, &keyBlock[10]);\r
                                mfEmlSetMem(keyBlock, FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1, 1);\r
-                       }               \r
+                       }\r
                }\r
-               \r
+\r
                // Create dump file\r
                if (createDumpFile) {\r
-                       if ((fkeys = fopen("dumpkeys.bin","wb")) == NULL) { \r
+                       if ((fkeys = fopen("dumpkeys.bin","wb")) == NULL) {\r
                                PrintAndLog("Could not create file dumpkeys.bin");\r
                                free(e_sector);\r
                                return 1;\r
@@ -761,7 +760,7 @@ int CmdHF14AMfNested(const char *Cmd)
                        }\r
                        fclose(fkeys);\r
                }\r
-               \r
+\r
                free(e_sector);\r
        }\r
        return 0;\r
@@ -776,7 +775,7 @@ int CmdHF14AMfNestedHard(const char *Cmd)
        uint8_t trgKeyType = 0;\r
        uint8_t key[6] = {0, 0, 0, 0, 0, 0};\r
        uint8_t trgkey[6] = {0, 0, 0, 0, 0, 0};\r
-       \r
+\r
        char ctmp;\r
        ctmp = param_getchar(Cmd, 0);\r
 \r
@@ -799,15 +798,15 @@ int CmdHF14AMfNestedHard(const char *Cmd)
                PrintAndLog("Add the known target key to check if it is present in the remaining key space:");\r
                PrintAndLog("      sample5: hf mf hardnested 0 A A0A1A2A3A4A5 4 A FFFFFFFFFFFF");\r
                return 0;\r
-       }       \r
-       \r
+       }\r
+\r
        bool know_target_key = false;\r
        bool nonce_file_read = false;\r
        bool nonce_file_write = false;\r
        bool slow = false;\r
        int tests = 0;\r
-       \r
-       \r
+\r
+\r
        if (ctmp == 'R' || ctmp == 'r') {\r
                nonce_file_read = true;\r
                if (!param_gethex(Cmd, 1, trgkey, 12)) {\r
@@ -825,15 +824,15 @@ int CmdHF14AMfNestedHard(const char *Cmd)
                        PrintAndLog("Key type must be A or B");\r
                        return 1;\r
                }\r
-               if (ctmp != 'A' && ctmp != 'a') { \r
+               if (ctmp != 'A' && ctmp != 'a') {\r
                        keyType = 1;\r
                }\r
-               \r
+\r
                if (param_gethex(Cmd, 2, key, 12)) {\r
                        PrintAndLog("Key must include 12 HEX symbols");\r
                        return 1;\r
                }\r
-               \r
+\r
                trgBlockNo = param_get8(Cmd, 3);\r
                ctmp = param_getchar(Cmd, 4);\r
                if (ctmp != 'a' && ctmp != 'A' && ctmp != 'b' && ctmp != 'B') {\r
@@ -864,8 +863,8 @@ int CmdHF14AMfNestedHard(const char *Cmd)
                }\r
        }\r
 \r
-       PrintAndLog("--target block no:%3d, target key type:%c, known target key: 0x%02x%02x%02x%02x%02x%02x%s, file action: %s, Slow: %s, Tests: %d ", \r
-                       trgBlockNo, \r
+       PrintAndLog("--target block no:%3d, target key type:%c, known target key: 0x%02x%02x%02x%02x%02x%02x%s, file action: %s, Slow: %s, Tests: %d ",\r
+                       trgBlockNo,\r
                        trgKeyType?'B':'A',\r
                        trgkey[0], trgkey[1], trgkey[2], trgkey[3], trgkey[4], trgkey[5],\r
                        know_target_key?"":" (not set)",\r
@@ -900,14 +899,14 @@ int CmdHF14AMfChk(const char *Cmd)
                PrintAndLog("              hf mf chk *1 ? t");\r
                PrintAndLog("              hf mf chk *1 ? d");\r
                return 0;\r
-       }       \r
+       }\r
 \r
        FILE * f;\r
        char filename[FILE_PATH_SIZE]={0};\r
        char buf[13];\r
        uint8_t *keyBlock = NULL, *p;\r
        uint16_t stKeyBlock = 20;\r
-       \r
+\r
        int i, res;\r
        int     keycnt = 0;\r
        char ctmp       = 0x00;\r
@@ -915,7 +914,7 @@ int CmdHF14AMfChk(const char *Cmd)
        uint8_t SectorsCnt = 1;\r
        uint8_t keyType = 0;\r
        uint64_t key64 = 0;\r
-       \r
+\r
        int transferToEml = 0;\r
        int createDumpFile = 0;\r
 \r
@@ -944,7 +943,7 @@ int CmdHF14AMfChk(const char *Cmd)
        {\r
                num_to_bytes(defaultKeys[defaultKeyCounter], 6, (uint8_t*)(keyBlock + defaultKeyCounter * 6));\r
        }\r
-       \r
+\r
        if (param_getchar(Cmd, 0)=='*') {\r
                blockNo = 3;\r
                switch(param_getchar(Cmd+1, 0)) {\r
@@ -957,9 +956,9 @@ int CmdHF14AMfChk(const char *Cmd)
        }\r
        else\r
                blockNo = param_get8(Cmd, 0);\r
-       \r
+\r
        ctmp = param_getchar(Cmd, 1);\r
-       switch (ctmp) { \r
+       switch (ctmp) {\r
        case 'a': case 'A':\r
                keyType = !0;\r
                break;\r
@@ -974,11 +973,11 @@ int CmdHF14AMfChk(const char *Cmd)
                free(keyBlock);\r
                return 1;\r
        };\r
-       \r
+\r
        ctmp = param_getchar(Cmd, 2);\r
        if              (ctmp == 't' || ctmp == 'T') transferToEml = 1;\r
        else if (ctmp == 'd' || ctmp == 'D') createDumpFile = 1;\r
-       \r
+\r
        for (i = transferToEml || createDumpFile; param_getchar(Cmd, 2 + i); i++) {\r
                if (!param_gethex(Cmd, 2 + i, keyBlock + 6 * keycnt, 12)) {\r
                        if ( stKeyBlock - keycnt < 2) {\r
@@ -1001,21 +1000,21 @@ int CmdHF14AMfChk(const char *Cmd)
                                free(keyBlock);\r
                                return 2;\r
                        }\r
-                       \r
+\r
                        if ( (f = fopen( filename , "r")) ) {\r
                                while( fgets(buf, sizeof(buf), f) ){\r
                                        if (strlen(buf) < 12 || buf[11] == '\n')\r
                                                continue;\r
-                               \r
+\r
                                        while (fgetc(f) != '\n' && !feof(f)) ;  //goto next line\r
-                                       \r
+\r
                                        if( buf[0]=='#' ) continue;     //The line start with # is comment, skip\r
 \r
                                        if (!isxdigit(buf[0])){\r
                                                PrintAndLog("File content error. '%s' must include 12 HEX symbols",buf);\r
                                                continue;\r
                                        }\r
-                                       \r
+\r
                                        buf[12] = 0;\r
 \r
                                        if ( stKeyBlock - keycnt < 2) {\r
@@ -1039,11 +1038,11 @@ int CmdHF14AMfChk(const char *Cmd)
                                PrintAndLog("File: %s: not found or locked.", filename);\r
                                free(keyBlock);\r
                                return 1;\r
-                       \r
+\r
                        }\r
                }\r
        }\r
-       \r
+\r
        if (keycnt == 0) {\r
                PrintAndLog("No key specified, trying default keys");\r
                for (;keycnt < defaultKeysSize; keycnt++)\r
@@ -1051,7 +1050,7 @@ int CmdHF14AMfChk(const char *Cmd)
                                (keyBlock + 6*keycnt)[0],(keyBlock + 6*keycnt)[1], (keyBlock + 6*keycnt)[2],\r
                                (keyBlock + 6*keycnt)[3], (keyBlock + 6*keycnt)[4],     (keyBlock + 6*keycnt)[5], 6);\r
        }\r
-       \r
+\r
        // initialize storage for found keys\r
        bool validKey[2][40];\r
        uint8_t foundKey[2][40][6];\r
@@ -1063,7 +1062,7 @@ int CmdHF14AMfChk(const char *Cmd)
                        }\r
                }\r
        }\r
-       \r
+\r
        for ( int t = !keyType; t < 2; keyType==2?(t++):(t=2) ) {\r
                int b=blockNo;\r
                for (int i = 0; i < SectorsCnt; ++i) {\r
@@ -1077,12 +1076,12 @@ int CmdHF14AMfChk(const char *Cmd)
                                                PrintAndLog("Found valid key:[%012" PRIx64 "]",key64);\r
                                                num_to_bytes(key64, 6, foundKey[t][i]);\r
                                                validKey[t][i] = true;\r
-                                       } \r
+                                       }\r
                                } else {\r
                                        PrintAndLog("Command execute timeout");\r
                                }\r
                        }\r
-                       b<127?(b+=4):(b+=16);   \r
+                       b<127?(b+=4):(b+=16);\r
                }\r
        }\r
 \r
@@ -1104,7 +1103,7 @@ int CmdHF14AMfChk(const char *Cmd)
 \r
        if (createDumpFile) {\r
                FILE *fkeys = fopen("dumpkeys.bin","wb");\r
-               if (fkeys == NULL) { \r
+               if (fkeys == NULL) {\r
                        PrintAndLog("Could not create file dumpkeys.bin");\r
                        free(keyBlock);\r
                        return 1;\r
@@ -1205,11 +1204,11 @@ void readerAttack(nonces_t ar_resp[], bool setEmulatorMem, bool doStandardAttack
                                        PrintAndLog("block data must include 32 HEX symbols");\r
                                        return;\r
                                }\r
-                               \r
+\r
                                UsbCommand c = {CMD_MIFARE_EML_MEMSET, {(stSector[i]*4+3), 1, 0}};\r
                                memcpy(c.d.asBytes, memBlock, 16);\r
                                clearCommandBuffer();\r
-                               SendCommand(&c);                        \r
+                               SendCommand(&c);\r
                        }\r
                }\r
        }\r
@@ -1241,7 +1240,7 @@ int usage_hf14_mf1ksim(void) {
        PrintAndLog("           hf mf sim u 112233445566778899AA");\r
        PrintAndLog("           hf mf sim f uids.txt");\r
        PrintAndLog("           hf mf sim u 0a0a0a0a e");\r
-               \r
+\r
        return 0;\r
 }\r
 \r
@@ -1344,9 +1343,9 @@ int CmdHF14AMf1kSim(const char *Cmd) {
                        memset(buf, 0, sizeof(buf));\r
                        memset(uid, 0, sizeof(uid));\r
 \r
-                       if (fgets(buf, sizeof(buf), f) == NULL) {                       \r
+                       if (fgets(buf, sizeof(buf), f) == NULL) {\r
                                if (count > 0) break;\r
-                               \r
+\r
                                PrintAndLog("File reading error.");\r
                                fclose(f);\r
                                return 2;\r
@@ -1358,7 +1357,7 @@ int CmdHF14AMf1kSim(const char *Cmd) {
                                case 20: flags |= FLAG_10B_UID_IN_DATA; break; //not complete\r
                                case 14: flags |= FLAG_7B_UID_IN_DATA; break;\r
                                case  8: flags |= FLAG_4B_UID_IN_DATA; break;\r
-                               default: \r
+                               default:\r
                                        PrintAndLog("uid in file wrong length at %d (length: %d) [%s]",count, uidlen, buf);\r
                                        fclose(f);\r
                                        return 2;\r
@@ -1367,10 +1366,10 @@ int CmdHF14AMf1kSim(const char *Cmd) {
                        for (uint8_t i = 0; i < uidlen; i += 2) {\r
                                sscanf(&buf[i], "%02x", (unsigned int *)&uid[i / 2]);\r
                        }\r
-                       \r
+\r
                        PrintAndLog("mf 1k sim uid: %s, numreads:%d, flags:%d (0x%02x) - press button to abort",\r
                                        flags & FLAG_4B_UID_IN_DATA ? sprint_hex(uid,4):\r
-                                               flags & FLAG_7B_UID_IN_DATA     ? sprint_hex(uid,7): \r
+                                               flags & FLAG_7B_UID_IN_DATA     ? sprint_hex(uid,7):\r
                                                        flags & FLAG_10B_UID_IN_DATA ? sprint_hex(uid,10): "N/A"\r
                                        , exitAfterNReads, flags, flags);\r
 \r
@@ -1400,7 +1399,7 @@ int CmdHF14AMf1kSim(const char *Cmd) {
 \r
                PrintAndLog("mf 1k sim uid: %s, numreads:%d, flags:%d (0x%02x) ",\r
                                flags & FLAG_4B_UID_IN_DATA ? sprint_hex(uid,4):\r
-                                       flags & FLAG_7B_UID_IN_DATA     ? sprint_hex(uid,7): \r
+                                       flags & FLAG_7B_UID_IN_DATA     ? sprint_hex(uid,7):\r
                                                flags & FLAG_10B_UID_IN_DATA ? sprint_hex(uid,10): "N/A"\r
                                , exitAfterNReads, flags, flags);\r
 \r
@@ -1444,7 +1443,7 @@ int CmdHF14AMfDbg(const char *Cmd)
                PrintAndLog(" 4 - print even debug messages in timing critical functions");\r
                PrintAndLog("     Note: this option therefore may cause malfunction itself");\r
                return 0;\r
-       }       \r
+       }\r
 \r
   UsbCommand c = {CMD_MIFARE_SET_DBGMODE, {dbgMode, 0, 0}};\r
   SendCommand(&c);\r
@@ -1461,8 +1460,8 @@ int CmdHF14AMfEGet(const char *Cmd)
                PrintAndLog("Usage:  hf mf eget <block number>");\r
                PrintAndLog(" sample: hf mf eget 0 ");\r
                return 0;\r
-       }       \r
-       \r
+       }\r
+\r
        blockNo = param_get8(Cmd, 0);\r
 \r
        PrintAndLog(" ");\r
@@ -1481,7 +1480,7 @@ int CmdHF14AMfEClear(const char *Cmd)
                PrintAndLog("Usage:  hf mf eclr");\r
                PrintAndLog("It set card emulator memory to empty data blocks and key A/B FFFFFFFFFFFF \n");\r
                return 0;\r
-       }       \r
+       }\r
 \r
   UsbCommand c = {CMD_MIFARE_EML_MEMCLR, {0, 0, 0}};\r
   SendCommand(&c);\r
@@ -1500,15 +1499,15 @@ int CmdHF14AMfESet(const char *Cmd)
                PrintAndLog("Usage:  hf mf eset <block number> <block data (32 hex symbols)>");\r
                PrintAndLog(" sample: hf mf eset 1 000102030405060708090a0b0c0d0e0f ");\r
                return 0;\r
-       }       \r
-       \r
+       }\r
+\r
        blockNo = param_get8(Cmd, 0);\r
-       \r
+\r
        if (param_gethex(Cmd, 1, memBlock, 32)) {\r
                PrintAndLog("block data must include 32 HEX symbols");\r
                return 1;\r
        }\r
-       \r
+\r
        //  1 - blocks count\r
        UsbCommand c = {CMD_MIFARE_EML_MEMSET, {blockNo, 1, 0}};\r
        memcpy(c.d.asBytes, memBlock, 16);\r
@@ -1526,9 +1525,9 @@ int CmdHF14AMfELoad(const char *Cmd)
        uint8_t buf8[64] = {0x00};\r
        int i, len, blockNum, numBlocks;\r
        int nameParamNo = 1;\r
-       \r
+\r
        char ctmp = param_getchar(Cmd, 0);\r
-               \r
+\r
        if ( ctmp == 'h' || ctmp == 0x00) {\r
                PrintAndLog("It loads emul dump from the file `filename.eml`");\r
                PrintAndLog("Usage:  hf mf eload [card memory] <file name w/o `.eml`>");\r
@@ -1537,11 +1536,11 @@ int CmdHF14AMfELoad(const char *Cmd)
                PrintAndLog(" sample: hf mf eload filename");\r
                PrintAndLog("         hf mf eload 4 filename");\r
                return 0;\r
-       }       \r
+       }\r
 \r
        switch (ctmp) {\r
                case '0' : numBlocks = 5*4; break;\r
-               case '1' : \r
+               case '1' :\r
                case '\0': numBlocks = 16*4; break;\r
                case '2' : numBlocks = 32*4; break;\r
                case '4' : numBlocks = 256; break;\r
@@ -1552,33 +1551,33 @@ int CmdHF14AMfELoad(const char *Cmd)
        }\r
 \r
        len = param_getstr(Cmd,nameParamNo,filename);\r
-       \r
+\r
        if (len > FILE_PATH_SIZE - 5) len = FILE_PATH_SIZE - 5;\r
 \r
        fnameptr += len;\r
 \r
-       sprintf(fnameptr, ".eml"); \r
-       \r
+       sprintf(fnameptr, ".eml");\r
+\r
        // open file\r
        f = fopen(filename, "r");\r
        if (f == NULL) {\r
                PrintAndLog("File %s not found or locked", filename);\r
                return 1;\r
        }\r
-       \r
+\r
        blockNum = 0;\r
        while(!feof(f)){\r
                memset(buf, 0, sizeof(buf));\r
-               \r
+\r
                if (fgets(buf, sizeof(buf), f) == NULL) {\r
-                       \r
+\r
                        if (blockNum >= numBlocks) break;\r
-                       \r
+\r
                        PrintAndLog("File reading error.");\r
                        fclose(f);\r
                        return 2;\r
                }\r
-               \r
+\r
                if (strlen(buf) < 32){\r
                        if(strlen(buf) && feof(f))\r
                                break;\r
@@ -1586,11 +1585,11 @@ int CmdHF14AMfELoad(const char *Cmd)
                        fclose(f);\r
                        return 2;\r
                }\r
-               \r
+\r
                for (i = 0; i < 32; i += 2) {\r
                        sscanf(&buf[i], "%02x", (unsigned int *)&buf8[i / 2]);\r
                }\r
-               \r
+\r
                if (mfEmlSetMem(buf8, blockNum, 1)) {\r
                        PrintAndLog("Cant set emul block: %3d", blockNum);\r
                        fclose(f);\r
@@ -1598,12 +1597,12 @@ int CmdHF14AMfELoad(const char *Cmd)
                }\r
                printf(".");\r
                blockNum++;\r
-               \r
+\r
                if (blockNum >= numBlocks) break;\r
        }\r
        fclose(f);\r
        printf("\n");\r
-       \r
+\r
        if ((blockNum != numBlocks)) {\r
                PrintAndLog("File content error. Got %d must be %d blocks.",blockNum, numBlocks);\r
                return 4;\r
@@ -1621,12 +1620,12 @@ int CmdHF14AMfESave(const char *Cmd)
        uint8_t buf[64];\r
        int i, j, len, numBlocks;\r
        int nameParamNo = 1;\r
-       \r
+\r
        memset(filename, 0, sizeof(filename));\r
        memset(buf, 0, sizeof(buf));\r
 \r
        char ctmp = param_getchar(Cmd, 0);\r
-       \r
+\r
        if ( ctmp == 'h' || ctmp == 'H') {\r
                PrintAndLog("It saves emul dump into the file `filename.eml` or `cardID.eml`");\r
                PrintAndLog(" Usage:  hf mf esave [card memory] [file name w/o `.eml`]");\r
@@ -1636,11 +1635,11 @@ int CmdHF14AMfESave(const char *Cmd)
                PrintAndLog("         hf mf esave 4");\r
                PrintAndLog("         hf mf esave 4 filename");\r
                return 0;\r
-       }       \r
+       }\r
 \r
        switch (ctmp) {\r
                case '0' : numBlocks = 5*4; break;\r
-               case '1' : \r
+               case '1' :\r
                case '\0': numBlocks = 16*4; break;\r
                case '2' : numBlocks = 32*4; break;\r
                case '4' : numBlocks = 256; break;\r
@@ -1651,9 +1650,9 @@ int CmdHF14AMfESave(const char *Cmd)
        }\r
 \r
        len = param_getstr(Cmd,nameParamNo,filename);\r
-       \r
+\r
        if (len > FILE_PATH_SIZE - 5) len = FILE_PATH_SIZE - 5;\r
-       \r
+\r
        // user supplied filename?\r
        if (len < 1) {\r
                // get filename (UID from memory)\r
@@ -1671,8 +1670,8 @@ int CmdHF14AMfESave(const char *Cmd)
        }\r
 \r
        // add file extension\r
-       sprintf(fnameptr, ".eml"); \r
-       \r
+       sprintf(fnameptr, ".eml");\r
+\r
        // open file\r
        f = fopen(filename, "w+");\r
 \r
@@ -1680,7 +1679,7 @@ int CmdHF14AMfESave(const char *Cmd)
                PrintAndLog("Can't open file %s ", filename);\r
                return 1;\r
        }\r
-       \r
+\r
        // put hex\r
        for (i = 0; i < numBlocks; i++) {\r
                if (mfEmlGetMem(buf, i, 1)) {\r
@@ -1688,13 +1687,13 @@ int CmdHF14AMfESave(const char *Cmd)
                        break;\r
                }\r
                for (j = 0; j < 16; j++)\r
-                       fprintf(f, "%02X", buf[j]); \r
+                       fprintf(f, "%02X", buf[j]);\r
                fprintf(f,"\n");\r
        }\r
        fclose(f);\r
-       \r
+\r
        PrintAndLog("Saved %d blocks to file: %s", numBlocks, filename);\r
-       \r
+\r
   return 0;\r
 }\r
 \r
@@ -1703,7 +1702,7 @@ int CmdHF14AMfECFill(const char *Cmd)
 {\r
        uint8_t keyType = 0;\r
        uint8_t numSectors = 16;\r
-       \r
+\r
        if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {\r
                PrintAndLog("Usage:  hf mf ecfill <key A/B> [card memory]");\r
                PrintAndLog("  [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K");\r
@@ -1713,7 +1712,7 @@ int CmdHF14AMfECFill(const char *Cmd)
                PrintAndLog("Read card and transfer its data to emulator memory.");\r
                PrintAndLog("Keys must be laid in the emulator memory. \n");\r
                return 0;\r
-       }       \r
+       }\r
 \r
        char ctmp = param_getchar(Cmd, 0);\r
        if (ctmp != 'a' && ctmp != 'A' && ctmp != 'b' && ctmp != 'B') {\r
@@ -1725,12 +1724,12 @@ int CmdHF14AMfECFill(const char *Cmd)
        ctmp = param_getchar(Cmd, 1);\r
        switch (ctmp) {\r
                case '0' : numSectors = 5; break;\r
-               case '1' : \r
+               case '1' :\r
                case '\0': numSectors = 16; break;\r
                case '2' : numSectors = 32; break;\r
                case '4' : numSectors = 40; break;\r
                default:   numSectors = 16;\r
-       }       \r
+       }\r
 \r
        printf("--params: numSectors: %d, keyType:%d", numSectors, keyType);\r
        UsbCommand c = {CMD_MIFARE_EML_CARDLOAD, {numSectors, keyType, 0}};\r
@@ -1738,14 +1737,13 @@ int CmdHF14AMfECFill(const char *Cmd)
        return 0;\r
 }\r
 \r
-\r
 int CmdHF14AMfEKeyPrn(const char *Cmd)\r
 {\r
        int i;\r
        uint8_t numSectors;\r
        uint8_t data[16];\r
        uint64_t keyA, keyB;\r
-       \r
+\r
        if (param_getchar(Cmd, 0) == 'h') {\r
                PrintAndLog("It prints the keys loaded in the emulator memory");\r
                PrintAndLog("Usage:  hf mf ekeyprn [card memory]");\r
@@ -1753,19 +1751,19 @@ int CmdHF14AMfEKeyPrn(const char *Cmd)
                PrintAndLog("");\r
                PrintAndLog(" sample: hf mf ekeyprn 1");\r
                return 0;\r
-       }       \r
+       }\r
 \r
        char cmdp = param_getchar(Cmd, 0);\r
-       \r
+\r
        switch (cmdp) {\r
                case '0' : numSectors = 5; break;\r
-               case '1' : \r
+               case '1' :\r
                case '\0': numSectors = 16; break;\r
                case '2' : numSectors = 32; break;\r
                case '4' : numSectors = 40; break;\r
                default:   numSectors = 16;\r
-       }               \r
-       \r
+       }\r
+\r
        PrintAndLog("|---|----------------|----------------|");\r
        PrintAndLog("|sec|key A           |key B           |");\r
        PrintAndLog("|---|----------------|----------------|");\r
@@ -1779,11 +1777,10 @@ int CmdHF14AMfEKeyPrn(const char *Cmd)
                PrintAndLog("|%03d|  %012" PRIx64 "  |  %012" PRIx64 "  |", i, keyA, keyB);\r
        }\r
        PrintAndLog("|---|----------------|----------------|");\r
-       \r
+\r
        return 0;\r
 }\r
 \r
-\r
 int CmdHF14AMfCSetUID(const char *Cmd)\r
 {\r
        uint8_t wipeCard = 0;\r
@@ -1847,7 +1844,7 @@ int CmdHF14AMfCSetUID(const char *Cmd)
                        PrintAndLog("Can't set UID. error=%d", res);\r
                        return 1;\r
                }\r
-       \r
+\r
        PrintAndLog("old UID:%s", sprint_hex(oldUid, 4));\r
        PrintAndLog("new UID:%s", sprint_hex(uid, 4));\r
        return 0;\r
@@ -1858,7 +1855,7 @@ int CmdHF14AMfCSetBlk(const char *Cmd)
        uint8_t memBlock[16] = {0x00};\r
        uint8_t blockNo = 0;\r
        bool wipeCard = false;\r
-       int res;\r
+       int res, gen = 0;\r
 \r
        if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {\r
                PrintAndLog("Usage:  hf mf csetblk <block number> <block data (32 hex symbols)> [w]");\r
@@ -1866,7 +1863,9 @@ int CmdHF14AMfCSetBlk(const char *Cmd)
                PrintAndLog("Set block data for magic Chinese card (only works with such cards)");\r
                PrintAndLog("If you also want wipe the card then add 'w' at the end of the command line");\r
                return 0;\r
-       }       \r
+       }\r
+\r
+       gen = mfCIdentify();\r
 \r
        blockNo = param_get8(Cmd, 0);\r
 \r
@@ -1879,7 +1878,14 @@ int CmdHF14AMfCSetBlk(const char *Cmd)
        wipeCard = (ctmp == 'w' || ctmp == 'W');\r
        PrintAndLog("--block number:%2d data:%s", blockNo, sprint_hex(memBlock, 16));\r
 \r
-       res = mfCSetBlock(blockNo, memBlock, NULL, wipeCard, CSETBLOCK_SINGLE_OPER);\r
+       if (gen == 2) {\r
+               /* generation 1b magic card */\r
+               res = mfCSetBlock(blockNo, memBlock, NULL, wipeCard, CSETBLOCK_SINGLE_OPER | CSETBLOCK_MAGIC_1B);\r
+       } else {\r
+               /* generation 1a magic card by default */\r
+               res = mfCSetBlock(blockNo, memBlock, NULL, wipeCard, CSETBLOCK_SINGLE_OPER);\r
+       }\r
+\r
        if (res) {\r
                PrintAndLog("Can't write block. error=%d", res);\r
                return 1;\r
@@ -1893,33 +1899,44 @@ int CmdHF14AMfCLoad(const char *Cmd)
        FILE * f;\r
        char filename[FILE_PATH_SIZE] = {0x00};\r
        char * fnameptr = filename;\r
-       char buf[64] = {0x00};\r
-       uint8_t buf8[64] = {0x00};\r
+       char buf[256] = {0x00};\r
+       uint8_t buf8[256] = {0x00};\r
        uint8_t fillFromEmulator = 0;\r
-       int i, len, blockNum, flags=0;\r
-       \r
+       int i, len, blockNum, flags = 0, gen = 0, numblock = 64;\r
+\r
        if (param_getchar(Cmd, 0) == 'h' || param_getchar(Cmd, 0)== 0x00) {\r
                PrintAndLog("It loads magic Chinese card from the file `filename.eml`");\r
-               PrintAndLog("or from emulator memory (option `e`)");\r
-               PrintAndLog("Usage:  hf mf cload <file name w/o `.eml`>");\r
-               PrintAndLog("   or:  hf mf cload e ");\r
-               PrintAndLog(" sample: hf mf cload filename");\r
+               PrintAndLog("or from emulator memory (option `e`). 4K card: (option `4`)");\r
+               PrintAndLog("Usage:  hf mf cload [file name w/o `.eml`][e][4]");\r
+               PrintAndLog("   or:  hf mf cload e [4]");\r
+               PrintAndLog("Sample: hf mf cload filename");\r
+               PrintAndLog("        hf mf cload filname 4");\r
+               PrintAndLog("        hf mf cload e");\r
+               PrintAndLog("        hf mf cload e 4");\r
                return 0;\r
-       }       \r
+       }\r
 \r
        char ctmp = param_getchar(Cmd, 0);\r
        if (ctmp == 'e' || ctmp == 'E') fillFromEmulator = 1;\r
-       \r
+       ctmp = param_getchar(Cmd, 1);\r
+       if (ctmp == '4') numblock = 256;\r
+\r
+       gen = mfCIdentify();\r
+       PrintAndLog("Loading magic mifare %dK", numblock == 256 ? 4:1);\r
+\r
        if (fillFromEmulator) {\r
-               for (blockNum = 0; blockNum < 16 * 4; blockNum += 1) {\r
+               for (blockNum = 0; blockNum < numblock; blockNum += 1) {\r
                        if (mfEmlGetMem(buf8, blockNum, 1)) {\r
                                PrintAndLog("Cant get block: %d", blockNum);\r
                                return 2;\r
                        }\r
                        if (blockNum == 0) flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC;                               // switch on field and send magic sequence\r
                        if (blockNum == 1) flags = 0;                                                                                                   // just write\r
-                       if (blockNum == 16 * 4 - 1) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD;             // Done. Magic Halt and switch off field.\r
+                       if (blockNum == numblock - 1) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD;           // Done. Magic Halt and switch off field.\r
 \r
+                       if (gen == 2)\r
+                               /* generation 1b magic card */\r
+                               flags |= CSETBLOCK_MAGIC_1B;\r
                        if (mfCSetBlock(blockNum, buf8, NULL, 0, flags)) {\r
                                PrintAndLog("Cant set magic card block: %d", blockNum);\r
                                return 3;\r
@@ -1927,26 +1944,28 @@ int CmdHF14AMfCLoad(const char *Cmd)
                }\r
                return 0;\r
        } else {\r
-               len = strlen(Cmd);\r
+               param_getstr(Cmd, 0, filename);\r
+\r
+               len = strlen(filename);\r
                if (len > FILE_PATH_SIZE - 5) len = FILE_PATH_SIZE - 5;\r
 \r
-               memcpy(filename, Cmd, len);\r
+               //memcpy(filename, Cmd, len);\r
                fnameptr += len;\r
 \r
-               sprintf(fnameptr, ".eml"); \r
-       \r
+               sprintf(fnameptr, ".eml");\r
+\r
                // open file\r
                f = fopen(filename, "r");\r
                if (f == NULL) {\r
                        PrintAndLog("File not found or locked.");\r
                        return 1;\r
                }\r
-       \r
+\r
                blockNum = 0;\r
                while(!feof(f)){\r
-               \r
+\r
                        memset(buf, 0, sizeof(buf));\r
-                       \r
+\r
                        if (fgets(buf, sizeof(buf), f) == NULL) {\r
                                fclose(f);\r
                                PrintAndLog("File reading error.");\r
@@ -1965,21 +1984,25 @@ int CmdHF14AMfCLoad(const char *Cmd)
 \r
                        if (blockNum == 0) flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC;                               // switch on field and send magic sequence\r
                        if (blockNum == 1) flags = 0;                                                                                                   // just write\r
-                       if (blockNum == 16 * 4 - 1) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD;             // Done. Switch off field.\r
+                       if (blockNum == numblock - 1) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD;           // Done. Switch off field.\r
 \r
+                       if (gen == 2)\r
+                               /* generation 1b magic card */\r
+                               flags |= CSETBLOCK_MAGIC_1B;\r
                        if (mfCSetBlock(blockNum, buf8, NULL, 0, flags)) {\r
                                PrintAndLog("Can't set magic card block: %d", blockNum);\r
                                fclose(f);\r
                                return 3;\r
                        }\r
                        blockNum++;\r
-               \r
-                       if (blockNum >= 16 * 4) break;  // magic card type - mifare 1K\r
+\r
+                       if (blockNum >= numblock) break;  // magic card type - mifare 1K 64 blocks, mifare 4k 256 blocks\r
                }\r
                fclose(f);\r
-       \r
-               if (blockNum != 16 * 4 && blockNum != 32 * 4 + 8 * 16){\r
-                       PrintAndLog("File content error. There must be 64 blocks");\r
+\r
+               //if (blockNum != 16 * 4 && blockNum != 32 * 4 + 8 * 16){\r
+               if (blockNum != numblock){\r
+                       PrintAndLog("File content error. There must be %d blocks", numblock);\r
                        return 4;\r
                }\r
                PrintAndLog("Loaded from file: %s", filename);\r
@@ -1991,7 +2014,7 @@ int CmdHF14AMfCLoad(const char *Cmd)
 int CmdHF14AMfCGetBlk(const char *Cmd) {\r
        uint8_t memBlock[16];\r
        uint8_t blockNo = 0;\r
-       int res;\r
+       int res, gen = 0;\r
        memset(memBlock, 0x00, sizeof(memBlock));\r
 \r
        if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {\r
@@ -1999,55 +2022,77 @@ int CmdHF14AMfCGetBlk(const char *Cmd) {
                PrintAndLog("sample:  hf mf cgetblk 1");\r
                PrintAndLog("Get block data from magic Chinese card (only works with such cards)\n");\r
                return 0;\r
-       }       \r
+       }\r
+\r
+       gen = mfCIdentify();\r
 \r
        blockNo = param_get8(Cmd, 0);\r
 \r
        PrintAndLog("--block number:%2d ", blockNo);\r
 \r
-       res = mfCGetBlock(blockNo, memBlock, CSETBLOCK_SINGLE_OPER);\r
+       if (gen == 2) {\r
+               /* generation 1b magic card */\r
+               res = mfCGetBlock(blockNo, memBlock, CSETBLOCK_SINGLE_OPER | CSETBLOCK_MAGIC_1B);\r
+       } else {\r
+               /* generation 1a magic card by default */\r
+               res = mfCGetBlock(blockNo, memBlock, CSETBLOCK_SINGLE_OPER);\r
+       }\r
        if (res) {\r
                        PrintAndLog("Can't read block. error=%d", res);\r
                        return 1;\r
                }\r
-       \r
+\r
        PrintAndLog("block data:%s", sprint_hex(memBlock, 16));\r
        return 0;\r
 }\r
 \r
-\r
 int CmdHF14AMfCGetSc(const char *Cmd) {\r
        uint8_t memBlock[16] = {0x00};\r
        uint8_t sectorNo = 0;\r
-       int i, res, flags;\r
+       int i, res, flags, gen = 0, baseblock = 0, sect_size = 4;\r
 \r
        if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {\r
                PrintAndLog("Usage:  hf mf cgetsc <sector number>");\r
                PrintAndLog("sample:  hf mf cgetsc 0");\r
                PrintAndLog("Get sector data from magic Chinese card (only works with such cards)\n");\r
                return 0;\r
-       }       \r
+       }\r
 \r
        sectorNo = param_get8(Cmd, 0);\r
-       if (sectorNo > 15) {\r
-               PrintAndLog("Sector number must be in [0..15] as in MIFARE classic.");\r
+\r
+       if (sectorNo > 39) {\r
+               PrintAndLog("Sector number must be in [0..15] in MIFARE classic 1k and [0..39] in MIFARE classic 4k.");\r
                return 1;\r
        }\r
 \r
        PrintAndLog("--sector number:%d ", sectorNo);\r
 \r
+       gen = mfCIdentify();\r
+\r
        flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC;\r
-       for (i = 0; i < 4; i++) {\r
+       if (sectorNo < 32 ) {\r
+               baseblock = sectorNo * 4;\r
+       } else {\r
+               baseblock = 128 + 16 * (sectorNo - 32);\r
+\r
+       }\r
+       if (sectorNo > 31) sect_size = 16;\r
+\r
+       for (i = 0; i < sect_size; i++) {\r
                if (i == 1) flags = 0;\r
-               if (i == 3) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD;\r
+               if (i == sect_size - 1) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD;\r
 \r
-               res = mfCGetBlock(sectorNo * 4 + i, memBlock, flags);\r
+               if (gen == 2)\r
+                       /* generation 1b magic card */\r
+                       flags |= CSETBLOCK_MAGIC_1B;\r
+\r
+               res = mfCGetBlock(baseblock + i, memBlock, flags);\r
                if (res) {\r
-                       PrintAndLog("Can't read block. %d error=%d", sectorNo * 4 + i, res);\r
+                       PrintAndLog("Can't read block. %d error=%d", baseblock + i, res);\r
                        return 1;\r
                }\r
-       \r
-               PrintAndLog("block %3d data:%s", sectorNo * 4 + i, sprint_hex(memBlock, 16));\r
+\r
+               PrintAndLog("block %3d data:%s", baseblock + i, sprint_hex(memBlock, 16));\r
        }\r
        return 0;\r
 }\r
@@ -2059,37 +2104,50 @@ int CmdHF14AMfCSave(const char *Cmd) {
        char filename[FILE_PATH_SIZE] = {0x00};\r
        char * fnameptr = filename;\r
        uint8_t fillFromEmulator = 0;\r
-       uint8_t buf[64] = {0x00};\r
-       int i, j, len, flags;\r
-       \r
+       uint8_t buf[256] = {0x00};\r
+       int i, j, len, flags, gen = 0, numblock = 64;\r
+\r
        // memset(filename, 0, sizeof(filename));\r
        // memset(buf, 0, sizeof(buf));\r
 \r
        if (param_getchar(Cmd, 0) == 'h') {\r
                PrintAndLog("It saves `magic Chinese` card dump into the file `filename.eml` or `cardID.eml`");\r
-               PrintAndLog("or into emulator memory (option `e`)");\r
-               PrintAndLog("Usage:  hf mf esave [file name w/o `.eml`][e]");\r
-               PrintAndLog(" sample: hf mf esave ");\r
-               PrintAndLog("         hf mf esave filename");\r
-               PrintAndLog("         hf mf esave e \n");\r
+               PrintAndLog("or into emulator memory (option `e`). 4K card: (option `4`)");\r
+               PrintAndLog("Usage:  hf mf esave [file name w/o `.eml`][e][4]");\r
+               PrintAndLog("Sample: hf mf esave ");\r
+               PrintAndLog("        hf mf esave filename");\r
+               PrintAndLog("        hf mf esave e");\r
+               PrintAndLog("        hf mf esave 4");\r
+               PrintAndLog("        hf mf esave filename 4");\r
+               PrintAndLog("        hf mf esave e 4");\r
                return 0;\r
-       }       \r
+       }\r
 \r
        char ctmp = param_getchar(Cmd, 0);\r
        if (ctmp == 'e' || ctmp == 'E') fillFromEmulator = 1;\r
+       if (ctmp == '4') numblock = 256;\r
+       ctmp = param_getchar(Cmd, 1);\r
+       if (ctmp == '4') numblock = 256;\r
+\r
+       gen = mfCIdentify();\r
+       PrintAndLog("Saving magic mifare %dK", numblock == 256 ? 4:1);\r
 \r
        if (fillFromEmulator) {\r
                // put into emulator\r
                flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC;\r
-               for (i = 0; i < 16 * 4; i++) {\r
+               for (i = 0; i < numblock; i++) {\r
                        if (i == 1) flags = 0;\r
-                       if (i == 16 * 4 - 1) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD;\r
-               \r
+                       if (i == numblock - 1) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD;\r
+\r
+                       if (gen == 2)\r
+                               /* generation 1b magic card */\r
+                               flags |= CSETBLOCK_MAGIC_1B;\r
+\r
                        if (mfCGetBlock(i, buf, flags)) {\r
                                PrintAndLog("Cant get block: %d", i);\r
                                break;\r
                        }\r
-                       \r
+\r
                        if (mfEmlSetMem(buf, i, 1)) {\r
                                PrintAndLog("Cant set emul block: %d", i);\r
                                return 3;\r
@@ -2097,27 +2155,35 @@ int CmdHF14AMfCSave(const char *Cmd) {
                }\r
                return 0;\r
        } else {\r
-               len = strlen(Cmd);\r
+               param_getstr(Cmd, 0, filename);\r
+\r
+               len = strlen(filename);\r
                if (len > FILE_PATH_SIZE - 5) len = FILE_PATH_SIZE - 5;\r
-       \r
-               if (len < 1) {\r
+\r
+               ctmp = param_getchar(Cmd, 0);\r
+               if (len < 1 || (ctmp == '4')) {\r
                        // get filename\r
-                       if (mfCGetBlock(0, buf, CSETBLOCK_SINGLE_OPER)) {\r
+\r
+                       flags = CSETBLOCK_SINGLE_OPER;\r
+                       if (gen == 2)\r
+                               /* generation 1b magic card */\r
+                               flags |= CSETBLOCK_MAGIC_1B;\r
+                       if (mfCGetBlock(0, buf, flags)) {\r
                                PrintAndLog("Cant get block: %d", 0);\r
                                len = sprintf(fnameptr, "dump");\r
                                fnameptr += len;\r
                        }\r
                        else {\r
                                for (j = 0; j < 7; j++, fnameptr += 2)\r
-                                       sprintf(fnameptr, "%02x", buf[j]); \r
+                                       sprintf(fnameptr, "%02x", buf[j]);\r
                        }\r
                } else {\r
-                       memcpy(filename, Cmd, len);\r
+                       //memcpy(filename, Cmd, len);\r
                        fnameptr += len;\r
                }\r
 \r
-               sprintf(fnameptr, ".eml"); \r
-       \r
+               sprintf(fnameptr, ".eml");\r
+\r
                // open file\r
                f = fopen(filename, "w+");\r
 \r
@@ -2128,22 +2194,25 @@ int CmdHF14AMfCSave(const char *Cmd) {
 \r
                // put hex\r
                flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC;\r
-               for (i = 0; i < 16 * 4; i++) {\r
+               for (i = 0; i < numblock; i++) {\r
                        if (i == 1) flags = 0;\r
-                       if (i == 16 * 4 - 1) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD;\r
-               \r
+                       if (i == numblock - 1) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD;\r
+\r
+                       if (gen == 2)\r
+                               /* generation 1b magic card */\r
+                               flags |= CSETBLOCK_MAGIC_1B;\r
                        if (mfCGetBlock(i, buf, flags)) {\r
                                PrintAndLog("Cant get block: %d", i);\r
                                break;\r
                        }\r
                        for (j = 0; j < 16; j++)\r
-                               fprintf(f, "%02x", buf[j]); \r
+                               fprintf(f, "%02x", buf[j]);\r
                        fprintf(f,"\n");\r
                }\r
                fclose(f);\r
-       \r
+\r
                PrintAndLog("Saved to file: %s", filename);\r
-       \r
+\r
                return 0;\r
        }\r
 }\r
@@ -2156,7 +2225,7 @@ int CmdHF14AMfSniff(const char *Cmd){
        //bool wantSaveToEml = 0; TODO\r
        bool wantSaveToEmlFile = 0;\r
 \r
-       //var \r
+       //var\r
        int res = 0;\r
        int len = 0;\r
        int blockLen = 0;\r
@@ -2170,7 +2239,7 @@ int CmdHF14AMfSniff(const char *Cmd){
        uint8_t *buf = NULL;\r
        uint16_t bufsize = 0;\r
        uint8_t *bufPtr = NULL;\r
-       \r
+\r
        char ctmp = param_getchar(Cmd, 0);\r
        if ( ctmp == 'h' || ctmp == 'H' ) {\r
                PrintAndLog("It continuously gets data from the field and saves it to: log, emulator, emulator file.");\r
@@ -2182,8 +2251,8 @@ int CmdHF14AMfSniff(const char *Cmd){
                PrintAndLog("Usage:  hf mf sniff [l][d][e][f]");\r
                PrintAndLog("  sample: hf mf sniff l d e");\r
                return 0;\r
-       }       \r
-       \r
+       }\r
+\r
        for (int i = 0; i < 4; i++) {\r
                ctmp = param_getchar(Cmd, i);\r
                if (ctmp == 'l' || ctmp == 'L') wantLogToFile = true;\r
@@ -2191,7 +2260,7 @@ int CmdHF14AMfSniff(const char *Cmd){
                //if (ctmp == 'e' || ctmp == 'E') wantSaveToEml = true; TODO\r
                if (ctmp == 'f' || ctmp == 'F') wantSaveToEmlFile = true;\r
        }\r
-       \r
+\r
        printf("-------------------------------------------------------------------------\n");\r
        printf("Executing command. \n");\r
        printf("Press the key on the proxmark3 device to abort both proxmark3 and client.\n");\r
@@ -2211,7 +2280,7 @@ int CmdHF14AMfSniff(const char *Cmd){
                        printf("\naborted via keyboard!\n");\r
                        break;\r
                }\r
-               \r
+\r
                UsbCommand resp;\r
                if (WaitForResponseTimeout(CMD_ACK,&resp,2000)) {\r
                        res = resp.arg[0] & 0xff;\r
@@ -2268,24 +2337,24 @@ int CmdHF14AMfSniff(const char *Cmd){
                                                memcpy(atqa, bufPtr + 2 + 7, 2);\r
                                                uid_len = (atqa[0] & 0xC0) == 0x40 ? 7 : 4;\r
                                                sak = bufPtr[11];\r
-                                               PrintAndLog("tag select uid:%s atqa:0x%02x%02x sak:0x%02x", \r
+                                               PrintAndLog("tag select uid:%s atqa:0x%02x%02x sak:0x%02x",\r
                                                        sprint_hex(uid + (7 - uid_len), uid_len),\r
-                                                       atqa[1], \r
-                                                       atqa[0], \r
+                                                       atqa[1],\r
+                                                       atqa[0],\r
                                                        sak);\r
                                                if (wantLogToFile || wantDecrypt) {\r
                                                        FillFileNameByUID(logHexFileName, uid + (7 - uid_len), ".log", uid_len);\r
                                                        AddLogCurrentDT(logHexFileName);\r
-                                               }                                               \r
-                                               if (wantDecrypt) \r
+                                               }\r
+                                               if (wantDecrypt)\r
                                                        mfTraceInit(uid, atqa, sak, wantSaveToEmlFile);\r
                                        } else {\r
                                                PrintAndLog("%s(%d):%s", isTag ? "TAG":"RDR", num, sprint_hex(bufPtr, len));\r
-                                               if (wantLogToFile) \r
+                                               if (wantLogToFile)\r
                                                        AddLogHex(logHexFileName, isTag ? "TAG: ":"RDR: ", bufPtr, len);\r
-                                               if (wantDecrypt) \r
+                                               if (wantDecrypt)\r
                                                        mfTraceDecode(bufPtr, len, wantSaveToEmlFile);\r
-                                               num++;  \r
+                                               num++;\r
                                        }\r
                                        bufPtr += len;\r
                                        bufPtr += ((len-1)/8+1);        // ignore parity\r
index 49c9ea39ef23a15f1b13a1518ec781e3aeef0f90..6a5a2fbe927e5a74dbaae87c9a74f5fea7c770fd 100644 (file)
@@ -45,6 +45,7 @@
 #include "cmdlfjablotron.h" //for jablotron menu
 #include "cmdlfnoralsy.h"// for noralsy menu
 #include "cmdlfsecurakey.h"//for securakey menu
+#include "cmdlfpac.h"    // for pac menu
 
 bool g_lf_threshold_set = false;
 static int CmdHelp(const char *Cmd);
@@ -349,7 +350,8 @@ bool lf_read(bool silent, uint32_t samples) {
                        return false;
                }
        }
-       getSamples(resp.arg[0], silent);
+       // resp.arg[0] is bits read not bytes read.
+       getSamples(resp.arg[0]/8, silent);
 
        return true;
 }
@@ -1055,6 +1057,12 @@ int CmdLFfind(const char *Cmd)
                return CheckChipType(cmdp);
        }
 
+       ans=CmdPacDemod("");
+       if (ans>0) {
+               PrintAndLog("\nValid PAC/Stanley ID Found!");
+               return CheckChipType(cmdp);             
+       }
+
        PrintAndLog("\nNo Known Tags Found!\n");
        if (testRaw=='u' || testRaw=='U') {
                //ans=CheckChipType(cmdp);
@@ -1081,7 +1089,7 @@ int CmdLFfind(const char *Cmd)
                if (ans>0) {
                        PrintAndLog("Possible unknown PSK1 Modulated Tag Found above!\n\nCould also be PSK2 - try 'data rawdemod p2'");
                        PrintAndLog("\nCould also be PSK3 - [currently not supported]");
-                       PrintAndLog("\nCould also be NRZ - try 'data nrzrawdemod'");
+                       PrintAndLog("\nCould also be NRZ - try 'data rawdemod nr'");
                        return CheckChipType(cmdp);
                }
                ans = CheckChipType(cmdp);
@@ -1105,6 +1113,7 @@ static command_t CommandTable[] =
        {"jablotron",   CmdLFJablotron,     1, "{ Jablotron RFIDs...         }"},
        {"nexwatch",    CmdLFNexWatch,      1, "{ NexWatch RFIDs...          }"},
        {"noralsy",     CmdLFNoralsy,       1, "{ Noralsy RFIDs...           }"},
+       {"pac",         CmdLFPac,           1, "{ PAC/Stanley RFIDs...       }"},
        {"paradox",     CmdLFParadox,       1, "{ Paradox RFIDs...           }"},
        {"presco",      CmdLFPresco,        1, "{ Presco RFIDs...            }"},
        {"pcf7931",     CmdLFPCF7931,       1, "{ PCF7931 CHIPs...           }"},
index f8e00e9b5d829fafa25e1359bc14d00f99a5b0a1..013c2f3fb427be478c318ff365b44d9e4f45692f 100644 (file)
@@ -405,7 +405,7 @@ int CmdEM410xBrute(const char *Cmd)
                        return 0;
                }
                                
-               sprintf(testuid, "%010lX", bytes_to_num(uidBlock + 5*c, 5));
+               sprintf(testuid, "%010" PRIX64, bytes_to_num(uidBlock + 5*c, 5));
                PrintAndLog("Bruteforce %d / %d: simulating UID  %s, clock %d", c + 1, uidcnt, testuid, clock);
                
                ConstructEM410xEmulGraph(testuid, clock);
index fd8e214821b9985ead1a4cb692b10243ff10af5c..19b5a1424a2471e7988c21126c7af2100d60d254 100644 (file)
@@ -120,20 +120,20 @@ int CmdHIDReadFSK(const char *Cmd)
 
 int CmdHIDSim(const char *Cmd)
 {
-  unsigned int hi = 0, lo = 0;
-  int n = 0, i = 0;
+       uint32_t hi = 0, lo = 0;
+       int n = 0, i = 0;
 
-  while (sscanf(&Cmd[i++], "%1x", &n ) == 1) {
-    hi = (hi << 4) | (lo >> 28);
-    lo = (lo << 4) | (n & 0xf);
-  }
+       while (sscanf(&Cmd[i++], "%1x", &n ) == 1) {
+               hi = (hi << 4) | (lo >> 28);
+               lo = (lo << 4) | (n & 0xf);
+       }
 
-  PrintAndLog("Emulating tag with ID %x%16x", hi, lo);
-  PrintAndLog("Press pm3-button to abort simulation");
+       PrintAndLog("Emulating tag with ID %x%08x", hi, lo);
+       PrintAndLog("Press pm3-button to abort simulation");
 
-  UsbCommand c = {CMD_HID_SIM_TAG, {hi, lo, 0}};
-  SendCommand(&c);
-  return 0;
+       UsbCommand c = {CMD_HID_SIM_TAG, {hi, lo, 0}};
+       SendCommand(&c);
+       return 0;
 }
 
 int CmdHIDClone(const char *Cmd)
index de1757e9ee35243a5ae1fab388eec03addc3f55f..8ec04cbb7ef4e4bc1ab88754b70373390a9774fd 100644 (file)
@@ -96,8 +96,12 @@ int CmdIndalaDemod(const char *Cmd) {
        uint8_t rawbits[4096];
        int rawbit = 0;
        int worst = 0, worstPos = 0;
-       // PrintAndLog("Expecting a bit less than %d raw bits", GraphTraceLen / 32);
+
+       //clear clock grid and demod plot
+       setClockGrid(0, 0);
+       DemodBufferLen = 0;
        
+       // PrintAndLog("Expecting a bit less than %d raw bits", GraphTraceLen / 32);
        // loop through raw signal - since we know it is psk1 rf/32 fc/2 skip every other value (+=2)
        for (i = 0; i < GraphTraceLen-1; i += 2) {
                count += 1;
index c71928ece3a88606e79672fa70904b523db498a2..4ccd55384f247ab4fb42aec716941751e075a9b4 100644 (file)
@@ -133,20 +133,21 @@ int CmdIOClone(const char *Cmd)
 {
   unsigned int hi = 0, lo = 0;
   int n = 0, i = 0;
+  char ch;
   UsbCommand c;
 
-  
-  //if (1 == sscanf(str, "0x%"SCNx32, &hi)) {
-    // value now contains the value in the string--decimal 255, in this case.
-  //}
-  
   while (sscanf(&Cmd[i++], "%1x", &n ) == 1) {
       hi = (hi << 4) | (lo >> 28);
       lo = (lo << 4) | (n & 0xf);
   }
 
-  PrintAndLog("Cloning tag with ID %08x %08x", hi, lo);
-  PrintAndLog("Press pm3-button to abort simulation");
+  if (sscanf(&Cmd[--i], "%c", &ch) == 1) {
+         PrintAndLog("Usage:    lf io clone <tag-ID>");
+         return 0;
+  }
+  
+  PrintAndLog("Cloning ioProx tag with ID %08x %08x", hi, lo);
+
   c.cmd = CMD_IO_CLONE_TAG;
   c.arg[0] = hi;
   c.arg[1] = lo;
diff --git a/client/cmdlfpac.c b/client/cmdlfpac.c
new file mode 100644 (file)
index 0000000..ef6b394
--- /dev/null
@@ -0,0 +1,100 @@
+//-----------------------------------------------------------------------------
+//
+// 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
+// the license.
+//-----------------------------------------------------------------------------
+// Low frequency Stanley/PAC tag commands
+// NRZ, RF/32, 128 bits long (unknown cs)
+//-----------------------------------------------------------------------------
+#include "cmdlfpac.h"
+#include <string.h>
+#include <inttypes.h>
+#include "proxmark3.h"
+#include "ui.h"
+#include "util.h"
+#include "graph.h"
+#include "cmdparser.h"
+#include "cmddata.h"
+#include "cmdmain.h"
+#include "cmdlf.h"
+#include "lfdemod.h"    // preamble test
+
+static int CmdHelp(const char *Cmd);
+
+// by marshmellow
+// find PAC preamble in already demoded data
+int PacFind(uint8_t *dest, size_t *size) {
+       if (*size < 128) return -1; //make sure buffer has data
+       size_t startIdx = 0;
+       uint8_t preamble[] = {1,1,1,1,1,1,1,1,0,0,1,0,0,0,0,0,0,1,0};
+       if (!preambleSearch(dest, preamble, sizeof(preamble), size, &startIdx))
+               return -2; //preamble not found
+       if (*size != 128) return -3; //wrong demoded size
+       //return start position
+       return (int)startIdx;
+}
+
+//see NRZDemod for what args are accepted
+int CmdPacDemod(const char *Cmd) {
+
+       //NRZ
+       if (!NRZrawDemod(Cmd, false)) {
+               if (g_debugMode) PrintAndLog("DEBUG: Error - PAC: NRZ Demod failed");
+               return 0;
+       }
+       size_t size = DemodBufferLen;
+       int ans = PacFind(DemodBuffer, &size);
+       if (ans < 0) {
+               if (g_debugMode) {
+                       if (ans == -1)
+                               PrintAndLog("DEBUG: Error - PAC: too few bits found");
+                       else if (ans == -2)
+                               PrintAndLog("DEBUG: Error - PAC: preamble not found");
+                       else if (ans == -3)
+                               PrintAndLog("DEBUG: Error - PAC: Size not correct: %d", size);
+                       else
+                               PrintAndLog("DEBUG: Error - PAC: ans: %d", ans);
+               }
+               return 0;
+       }
+       setDemodBuf(DemodBuffer, 128, ans);
+       setClockGrid(g_DemodClock, g_DemodStartIdx + (ans*g_DemodClock));
+
+       //got a good demod
+       uint32_t raw1 = bytebits_to_byte(DemodBuffer   , 32);
+       uint32_t raw2 = bytebits_to_byte(DemodBuffer+32, 32);
+       uint32_t raw3 = bytebits_to_byte(DemodBuffer+64, 32);
+       uint32_t raw4 = bytebits_to_byte(DemodBuffer+96, 32);
+
+       // preamble     then appears to have marker bits of "10"                                                                                                                                       CS?    
+       // 11111111001000000 10 01001100 10 00001101 10 00001101 10 00001101 10 00001101 10 00001101 10 00001101 10 00001101 10 00001101 10 10001100 10 100000001
+       // unknown checksum 9 bits at the end
+       
+       PrintAndLog("PAC/Stanley Tag Found -- Raw: %08X%08X%08X%08X", raw1 ,raw2, raw3, raw4);
+       PrintAndLog("\nHow the Raw ID is translated by the reader is unknown");
+       return 1;
+}
+
+int CmdPacRead(const char *Cmd) {
+       lf_read(true, 4096*2 + 20);
+       return CmdPacDemod(Cmd);
+}
+
+static command_t CommandTable[] = {
+       {"help",  CmdHelp,    1, "This help"},
+       {"demod", CmdPacDemod,1, "Attempt to read and extract tag data from the GraphBuffer"},
+       {"read",  CmdPacRead, 0, "Attempt to read and extract tag data from the antenna"},
+       {NULL, NULL, 0, NULL}
+};
+
+int CmdLFPac(const char *Cmd) {
+       clearCommandBuffer();
+       CmdsParse(CommandTable, Cmd);
+       return 0;
+}
+
+int CmdHelp(const char *Cmd) {
+       CmdsHelp(CommandTable);
+       return 0;
+}
diff --git a/client/cmdlfpac.h b/client/cmdlfpac.h
new file mode 100644 (file)
index 0000000..99b35a5
--- /dev/null
@@ -0,0 +1,17 @@
+//-----------------------------------------------------------------------------
+//
+// 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
+// the license.
+//-----------------------------------------------------------------------------
+// Low frequency Securakey tag commands
+//-----------------------------------------------------------------------------
+#ifndef CMDLFPAC_H__
+#define CMDLFPAC_H__
+
+extern int CmdLFPac(const char *Cmd);
+extern int CmdPacRead(const char *Cmd);
+extern int CmdPacDemod(const char *Cmd);
+
+#endif
+
index 8085eedc909ec3cb259567ff5d94aa8dd648967c..8ae81250fb06fb3b995ec048d937291b9eabb099 100644 (file)
@@ -44,7 +44,7 @@ int CmdSecurakeyDemod(const char *Cmd) {
        //ASK / Manchester
        bool st = false;
        if (!ASKDemod_ext("40 0 0", false, false, 1, &st)) {
-               if (g_debugMode) PrintAndLog("DEBUG: Error - Noralsy: ASK/Manchester Demod failed");
+               if (g_debugMode) PrintAndLog("DEBUG: Error - Securakey: ASK/Manchester Demod failed");
                return 0;
        }
        if (st) return 0;
index 60cfcbbf5e723e1d70208281158ddbec45d93250..0c72a37c84b1cd9d341ff75891ad5b57e69728c9 100644 (file)
@@ -12,6 +12,7 @@
 
 #include "mfkey.h"
 
+#include "mifare.h"
 #include "crapto1/crapto1.h"
 
 
index ad5a863da0ae0095c30a222d7de146eca1c73a35..be32fe1bd890a8c9bd827907b0cf74e28f940a00 100644 (file)
 
 #include <stdint.h>
 #include <stdbool.h>
-
-typedef struct {
-                         uint32_t cuid;
-                         uint8_t  sector;
-                         uint8_t  keytype;
-                         uint32_t nonce;
-                         uint32_t ar;
-                         uint32_t nr;
-                         uint32_t at;
-                         uint32_t nonce2;
-                         uint32_t ar2;
-                         uint32_t nr2;
-                       } nonces_t;
+#include "mifare.h"
 
 extern bool mfkey32(nonces_t data, uint64_t *outputkey);
 extern bool mfkey32_moebius(nonces_t data, uint64_t *outputkey);
index 6b5e3ba2312df8e4a9742ff45a09a08b21e5411a..3b5247589a86b8e594e6d0102b267f6226ebd12e 100644 (file)
@@ -11,7 +11,7 @@
 #include "mifarehost.h"\r
 \r
 #include <stdio.h>\r
-#include <stdlib.h> \r
+#include <stdlib.h>\r
 #include <string.h>\r
 #include <pthread.h>\r
 \r
@@ -23,6 +23,8 @@
 #include "util.h"\r
 #include "iso14443crc.h"\r
 \r
+#include "mifare.h"\r
+\r
 // mifare tracer flags used in mfTraceDecode()\r
 #define TRACE_IDLE                                             0x00\r
 #define TRACE_AUTH1                                            0x01\r
@@ -52,7 +54,7 @@ static uint32_t intersection(uint64_t *list1, uint64_t *list2)
                return 0;\r
        }\r
        uint64_t *p1, *p2, *p3;\r
-       p1 = p3 = list1; \r
+       p1 = p3 = list1;\r
        p2 = list2;\r
 \r
        while ( *p1 != -1 && *p2 != -1 ) {\r
@@ -98,7 +100,7 @@ static uint32_t nonce2key(uint32_t uid, uint32_t nt, uint32_t nr, uint64_t par_i
        }\r
 \r
        keylist = (uint64_t*)states;\r
-       \r
+\r
        for (i = 0; keylist[i]; i++) {\r
                lfsr_rollback_word(states+i, uid^nt, 0);\r
                crypto1_get_lfsr(states+i, &key_recovered);\r
@@ -128,16 +130,16 @@ int mfDarkside(uint64_t *key)
        printf("Press button on the proxmark3 device to abort both proxmark3 and client.\n");\r
        printf("-------------------------------------------------------------------------\n");\r
 \r
-       \r
+\r
        while (true) {\r
                clearCommandBuffer();\r
                SendCommand(&c);\r
-               \r
+\r
                //flush queue\r
                while (ukbhit()) {\r
                        int c = getchar(); (void) c;\r
                }\r
-               \r
+\r
                // wait cycle\r
                while (true) {\r
                        printf(".");\r
@@ -146,7 +148,7 @@ int mfDarkside(uint64_t *key)
                                return -5;\r
                                break;\r
                        }\r
-                       \r
+\r
                        UsbCommand resp;\r
                        if (WaitForResponseTimeout(CMD_ACK, &resp, 1000)) {\r
                                isOK  = resp.arg[0];\r
@@ -160,7 +162,7 @@ int mfDarkside(uint64_t *key)
                                nr = bytes_to_num(resp.d.asBytes + 24, 4);\r
                                break;\r
                        }\r
-               }       \r
+               }\r
 \r
                if (par_list == 0 && c.arg[0] == true) {\r
                        PrintAndLog("Parity is all zero. Most likely this card sends NACK on every failed authentication.");\r
@@ -171,7 +173,7 @@ int mfDarkside(uint64_t *key)
                keycount = nonce2key(uid, nt, nr, par_list, ks_list, &keylist);\r
 \r
                if (keycount == 0) {\r
-                       PrintAndLog("Key not found (lfsr_common_prefix list is null). Nt=%08x", nt);    \r
+                       PrintAndLog("Key not found (lfsr_common_prefix list is null). Nt=%08x", nt);\r
                        PrintAndLog("This is expected to happen in 25%% of all cases. Trying again with a different reader nonce...");\r
                        continue;\r
                }\r
@@ -188,7 +190,7 @@ int mfDarkside(uint64_t *key)
                        PrintAndLog("Found %u possible keys. Trying to authenticate with each of them ...\n", keycount);\r
                } else {\r
                        PrintAndLog("Found a possible key. Trying to authenticate...\n");\r
-               }               \r
+               }\r
 \r
                *key = -1;\r
                uint8_t keyBlock[USB_CMD_DATA_SIZE];\r
@@ -205,8 +207,8 @@ int mfDarkside(uint64_t *key)
                        if (!mfCheckKeys(0, 0, false, size, keyBlock, key)) {\r
                                break;\r
                        }\r
-               }       \r
-               \r
+               }\r
+\r
                if (*key != -1) {\r
                        free(last_keylist);\r
                        free(keylist);\r
@@ -217,7 +219,7 @@ int mfDarkside(uint64_t *key)
                        last_keylist = keylist;\r
                }\r
        }\r
-       \r
+\r
        return 0;\r
 }\r
 \r
@@ -244,7 +246,7 @@ int Compare16Bits(const void * a, const void * b) {
        else return -1;\r
 }\r
 \r
-typedef \r
+typedef\r
        struct {\r
                union {\r
                        struct Crypto1State *slhead;\r
@@ -274,11 +276,11 @@ void* nested_worker_thread(void *arg)
        statelist->len = p1 - statelist->head.slhead;\r
        statelist->tail.sltail = --p1;\r
        qsort(statelist->head.slhead, statelist->len, sizeof(uint64_t), Compare16Bits);\r
-       \r
+\r
        return statelist->head.slhead;\r
 }\r
 \r
-int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t *resultKey, bool calibrate) \r
+int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t *resultKey, bool calibrate)\r
 {\r
        uint16_t i;\r
        uint32_t uid;\r
@@ -286,10 +288,10 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo,
 \r
        StateList_t statelists[2];\r
        struct Crypto1State *p1, *p2, *p3, *p4;\r
-       \r
+\r
        // flush queue\r
        WaitForResponseTimeout(CMD_ACK, NULL, 100);\r
-       \r
+\r
        UsbCommand c = {CMD_MIFARE_NESTED, {blockNo + keyType * 0x100, trgBlockNo + trgKeyType * 0x100, calibrate}};\r
        memcpy(c.d.asBytes, key, 6);\r
        SendCommand(&c);\r
@@ -301,10 +303,10 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo,
        if (resp.arg[0]) {\r
                return resp.arg[0];  // error during nested\r
        }\r
-               \r
+\r
        memcpy(&uid, resp.d.asBytes, 4);\r
        PrintAndLog("uid:%08x trgbl=%d trgkey=%x", uid, (uint16_t)resp.arg[2] & 0xff, (uint16_t)resp.arg[2] >> 8);\r
-       \r
+\r
        for (i = 0; i < 2; i++) {\r
                statelists[i].blockNo = resp.arg[2] & 0xff;\r
                statelists[i].keyType = (resp.arg[2] >> 8) & 0xff;\r
@@ -312,16 +314,16 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo,
                memcpy(&statelists[i].nt,  (void *)(resp.d.asBytes + 4 + i * 8 + 0), 4);\r
                memcpy(&statelists[i].ks1, (void *)(resp.d.asBytes + 4 + i * 8 + 4), 4);\r
        }\r
-       \r
+\r
        // calc keys\r
-       \r
+\r
        pthread_t thread_id[2];\r
-               \r
+\r
        // create and run worker threads\r
        for (i = 0; i < 2; i++) {\r
                pthread_create(thread_id + i, NULL, nested_worker_thread, &statelists[i]);\r
        }\r
-       \r
+\r
        // wait for threads to terminate:\r
        for (i = 0; i < 2; i++) {\r
                pthread_join(thread_id[i], (void*)&statelists[i].head.slhead);\r
@@ -331,7 +333,7 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo,
        // the first 16 Bits of the cryptostate already contain part of our key.\r
        // Create the intersection of the two lists based on these 16 Bits and\r
        // roll back the cryptostate\r
-       p1 = p3 = statelists[0].head.slhead; \r
+       p1 = p3 = statelists[0].head.slhead;\r
        p2 = p4 = statelists[1].head.slhead;\r
        while (p1 <= statelists[0].tail.sltail && p2 <= statelists[1].tail.sltail) {\r
                if (Compare16Bits(p1, p2) == 0) {\r
@@ -382,10 +384,10 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo,
                        break;\r
                }\r
        }\r
-       \r
+\r
        free(statelists[0].head.slhead);\r
        free(statelists[1].head.slhead);\r
-       \r
+\r
        return 0;\r
 }\r
 \r
@@ -403,7 +405,7 @@ int mfEmlGetMem(uint8_t *data, int blockNum, int blocksCount) {
 \r
 int mfEmlSetMem(uint8_t *data, int blockNum, int blocksCount) {\r
        UsbCommand c = {CMD_MIFARE_EML_MEMSET, {blockNum, blocksCount, 0}};\r
-       memcpy(c.d.asBytes, data, blocksCount * 16); \r
+       memcpy(c.d.asBytes, data, blocksCount * 16);\r
        SendCommand(&c);\r
        return 0;\r
 }\r
@@ -432,15 +434,15 @@ int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, bool wantWipe, uin
 \r
        uint8_t isOK = 0;\r
        UsbCommand c = {CMD_MIFARE_CSETBLOCK, {wantWipe, params & (0xFE | (uid == NULL ? 0:1)), blockNo}};\r
-       memcpy(c.d.asBytes, data, 16); \r
+       memcpy(c.d.asBytes, data, 16);\r
        SendCommand(&c);\r
 \r
   UsbCommand resp;\r
        if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {\r
                isOK  = resp.arg[0] & 0xff;\r
-               if (uid != NULL) \r
+               if (uid != NULL)\r
                        memcpy(uid, resp.d.asBytes, 4);\r
-               if (!isOK) \r
+               if (!isOK)\r
                        return 2;\r
        } else {\r
                PrintAndLog("Command execute timeout");\r
@@ -452,8 +454,18 @@ int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, bool wantWipe, uin
 int mfCSetUID(uint8_t *uid, uint8_t *atqa, uint8_t *sak, uint8_t *oldUID, bool wantWipe) {\r
        uint8_t oldblock0[16] = {0x00};\r
        uint8_t block0[16] = {0x00};\r
+       int old, gen = 0;\r
+\r
+       gen = mfCIdentify();\r
+\r
+       if (gen == 2) {\r
+               /* generation 1b magic card */\r
+               old = mfCGetBlock(0, oldblock0, CSETBLOCK_SINGLE_OPER | CSETBLOCK_MAGIC_1B);\r
+       } else {\r
+               /* generation 1a magic card by default */\r
+               old = mfCGetBlock(0, oldblock0, CSETBLOCK_SINGLE_OPER);\r
+       }\r
 \r
-       int old = mfCGetBlock(0, oldblock0, CSETBLOCK_SINGLE_OPER);\r
        if (old == 0) {\r
                memcpy(block0, oldblock0, 16);\r
                PrintAndLog("old block 0:  %s", sprint_hex(block0,16));\r
@@ -463,7 +475,7 @@ int mfCSetUID(uint8_t *uid, uint8_t *atqa, uint8_t *sak, uint8_t *oldUID, bool w
 \r
        // fill in the new values\r
        // UID\r
-       memcpy(block0, uid, 4); \r
+       memcpy(block0, uid, 4);\r
        // Mifare UID BCC\r
        block0[4] = block0[0]^block0[1]^block0[2]^block0[3];\r
        // mifare classic SAK(byte 5) and ATQA(byte 6 and 7, reversed)\r
@@ -474,7 +486,14 @@ int mfCSetUID(uint8_t *uid, uint8_t *atqa, uint8_t *sak, uint8_t *oldUID, bool w
                block0[7]=atqa[0];\r
        }\r
        PrintAndLog("new block 0:  %s", sprint_hex(block0,16));\r
-       return mfCSetBlock(0, block0, oldUID, wantWipe, CSETBLOCK_SINGLE_OPER);\r
+\r
+       if (gen == 2) {\r
+               /* generation 1b magic card */\r
+               return mfCSetBlock(0, block0, oldUID, wantWipe, CSETBLOCK_SINGLE_OPER | CSETBLOCK_MAGIC_1B);\r
+       } else {\r
+               /* generation 1a magic card by default */\r
+               return mfCSetBlock(0, block0, oldUID, wantWipe, CSETBLOCK_SINGLE_OPER);\r
+       }\r
 }\r
 \r
 // SNIFFER\r
@@ -508,7 +527,7 @@ int isTraceCardEmpty(void) {
 }\r
 \r
 int isBlockEmpty(int blockN) {\r
-       for (int i = 0; i < 16; i++) \r
+       for (int i = 0; i < 16; i++)\r
                if (traceCard[blockN * 16 + i] != 0) return 0;\r
 \r
        return 1;\r
@@ -520,15 +539,15 @@ int isBlockTrailer(int blockN) {
 \r
 int saveTraceCard(void) {\r
        FILE * f;\r
-       \r
+\r
        if ((!strlen(traceFileName)) || (isTraceCardEmpty())) return 0;\r
-       \r
+\r
        f = fopen(traceFileName, "w+");\r
        if ( !f ) return 1;\r
-       \r
+\r
        for (int i = 0; i < 64; i++) {  // blocks\r
                for (int j = 0; j < 16; j++)  // bytes\r
-                       fprintf(f, "%02x", *(traceCard + i * 16 + j)); \r
+                       fprintf(f, "%02x", *(traceCard + i * 16 + j));\r
                fprintf(f,"\n");\r
        }\r
        fclose(f);\r
@@ -540,10 +559,10 @@ int loadTraceCard(uint8_t *tuid) {
        char buf[64] = {0x00};\r
        uint8_t buf8[64] = {0x00};\r
        int i, blockNum;\r
-       \r
-       if (!isTraceCardEmpty()) \r
+\r
+       if (!isTraceCardEmpty())\r
                saveTraceCard();\r
-               \r
+\r
        memset(traceCard, 0x00, 4096);\r
        memcpy(traceCard, tuid + 3, 4);\r
 \r
@@ -551,11 +570,11 @@ int loadTraceCard(uint8_t *tuid) {
 \r
        f = fopen(traceFileName, "r");\r
        if (!f) return 1;\r
-       \r
+\r
        blockNum = 0;\r
-               \r
+\r
        while(!feof(f)){\r
-       \r
+\r
                memset(buf, 0, sizeof(buf));\r
                if (fgets(buf, sizeof(buf), f) == NULL) {\r
                        PrintAndLog("File reading error.");\r
@@ -583,20 +602,20 @@ int loadTraceCard(uint8_t *tuid) {
 \r
 int mfTraceInit(uint8_t *tuid, uint8_t *atqa, uint8_t sak, bool wantSaveToEmlFile) {\r
 \r
-       if (traceCrypto1) \r
+       if (traceCrypto1)\r
                crypto1_destroy(traceCrypto1);\r
 \r
        traceCrypto1 = NULL;\r
 \r
-       if (wantSaveToEmlFile) \r
+       if (wantSaveToEmlFile)\r
                loadTraceCard(tuid);\r
-               \r
+\r
        traceCard[4] = traceCard[0] ^ traceCard[1] ^ traceCard[2] ^ traceCard[3];\r
        traceCard[5] = sak;\r
        memcpy(&traceCard[6], atqa, 2);\r
        traceCurBlock = 0;\r
        uid = bytes_to_num(tuid + 3, 4);\r
-       \r
+\r
        traceState = TRACE_IDLE;\r
 \r
        return 0;\r
@@ -605,7 +624,7 @@ int mfTraceInit(uint8_t *tuid, uint8_t *atqa, uint8_t sak, bool wantSaveToEmlFil
 void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *data, int len, bool isEncrypted){\r
        uint8_t bt = 0;\r
        int i;\r
-       \r
+\r
        if (len != 1) {\r
                for (i = 0; i < len; i++)\r
                        data[i] = crypto1_byte(pcs, 0x00, isEncrypted) ^ data[i];\r
@@ -613,7 +632,7 @@ void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *data, int len, bool i
                bt = 0;\r
                for (i = 0; i < 4; i++)\r
                        bt |= (crypto1_bit(pcs, 0, isEncrypted) ^ BIT(data[0], i)) << i;\r
-                               \r
+\r
                data[0] = bt;\r
        }\r
        return;\r
@@ -628,24 +647,24 @@ int mfTraceDecode(uint8_t *data_src, int len, bool wantSaveToEmlFile) {
                traceState = TRACE_ERROR;\r
                return 1;\r
        }\r
-       \r
+\r
        memcpy(data, data_src, len);\r
        if ((traceCrypto1) && ((traceState == TRACE_IDLE) || (traceState > TRACE_AUTH_OK))) {\r
                mf_crypto1_decrypt(traceCrypto1, data, len, 0);\r
                PrintAndLog("dec> %s", sprint_hex(data, len));\r
-               AddLogHex(logHexFileName, "dec> ", data, len); \r
+               AddLogHex(logHexFileName, "dec> ", data, len);\r
        }\r
-       \r
+\r
        switch (traceState) {\r
-       case TRACE_IDLE: \r
+       case TRACE_IDLE:\r
                // check packet crc16!\r
                if ((len >= 4) && (!CheckCrc14443(CRC_14443_A, data, len))) {\r
                        PrintAndLog("dec> CRC ERROR!!!");\r
-                       AddLogLine(logHexFileName, "dec> ", "CRC ERROR!!!"); \r
+                       AddLogLine(logHexFileName, "dec> ", "CRC ERROR!!!");\r
                        traceState = TRACE_ERROR;  // do not decrypt the next commands\r
                        return 1;\r
                }\r
-               \r
+\r
                // AUTHENTICATION\r
                if ((len ==4) && ((data[0] == 0x60) || (data[0] == 0x61))) {\r
                        traceState = TRACE_AUTH1;\r
@@ -673,11 +692,11 @@ int mfTraceDecode(uint8_t *data_src, int len, bool wantSaveToEmlFile) {
                        traceState = TRACE_ERROR;  // do not decrypt the next commands\r
                        return 0;\r
                }\r
-               \r
+\r
                return 0;\r
        break;\r
-       \r
-       case TRACE_READ_DATA: \r
+\r
+       case TRACE_READ_DATA:\r
                if (len == 18) {\r
                        traceState = TRACE_IDLE;\r
 \r
@@ -694,7 +713,7 @@ int mfTraceDecode(uint8_t *data_src, int len, bool wantSaveToEmlFile) {
                }\r
        break;\r
 \r
-       case TRACE_WRITE_OK: \r
+       case TRACE_WRITE_OK:\r
                if ((len == 1) && (data[0] == 0x0a)) {\r
                        traceState = TRACE_WRITE_DATA;\r
 \r
@@ -705,7 +724,7 @@ int mfTraceDecode(uint8_t *data_src, int len, bool wantSaveToEmlFile) {
                }\r
        break;\r
 \r
-       case TRACE_WRITE_DATA: \r
+       case TRACE_WRITE_DATA:\r
                if (len == 18) {\r
                        traceState = TRACE_IDLE;\r
 \r
@@ -718,7 +737,7 @@ int mfTraceDecode(uint8_t *data_src, int len, bool wantSaveToEmlFile) {
                }\r
        break;\r
 \r
-       case TRACE_AUTH1: \r
+       case TRACE_AUTH1:\r
                if (len == 4) {\r
                        traceState = TRACE_AUTH2;\r
                        nt = bytes_to_num(data, 4);\r
@@ -729,7 +748,7 @@ int mfTraceDecode(uint8_t *data_src, int len, bool wantSaveToEmlFile) {
                }\r
        break;\r
 \r
-       case TRACE_AUTH2: \r
+       case TRACE_AUTH2:\r
                if (len == 8) {\r
                        traceState = TRACE_AUTH_OK;\r
 \r
@@ -742,12 +761,12 @@ int mfTraceDecode(uint8_t *data_src, int len, bool wantSaveToEmlFile) {
                }\r
        break;\r
 \r
-       case TRACE_AUTH_OK: \r
+       case TRACE_AUTH_OK:\r
                if (len ==4) {\r
                        traceState = TRACE_IDLE;\r
 \r
                        at_enc = bytes_to_num(data, 4);\r
-                       \r
+\r
                        //  decode key here)\r
                        ks2 = ar_enc ^ prng_successor(nt, 64);\r
                        ks3 = at_enc ^ prng_successor(nt, 96);\r
@@ -759,11 +778,11 @@ int mfTraceDecode(uint8_t *data_src, int len, bool wantSaveToEmlFile) {
 \r
                        crypto1_get_lfsr(revstate, &lfsr);\r
                        printf("key> %x%x\n", (unsigned int)((lfsr & 0xFFFFFFFF00000000) >> 32), (unsigned int)(lfsr & 0xFFFFFFFF));\r
-                       AddLogUint64(logHexFileName, "key> ", lfsr); \r
-                       \r
+                       AddLogUint64(logHexFileName, "key> ", lfsr);\r
+\r
                        int blockShift = ((traceCurBlock & 0xFC) + 3) * 16;\r
                        if (isBlockEmpty((traceCurBlock & 0xFC) + 3)) memcpy(traceCard + blockShift + 6, trailerAccessBytes, 4);\r
-                       \r
+\r
                        if (traceCurKey) {\r
                                num_to_bytes(lfsr, 6, traceCard + blockShift + 10);\r
                        } else {\r
@@ -774,10 +793,10 @@ int mfTraceDecode(uint8_t *data_src, int len, bool wantSaveToEmlFile) {
                        if (traceCrypto1) {\r
                                crypto1_destroy(traceCrypto1);\r
                        }\r
-                       \r
+\r
                        // set cryptosystem state\r
                        traceCrypto1 = lfsr_recovery64(ks2, ks3);\r
-                       \r
+\r
 //     nt = crypto1_word(traceCrypto1, nt ^ uid, 1) ^ nt;\r
 \r
        /*      traceCrypto1 = crypto1_create(lfsr); // key in lfsr\r
@@ -785,7 +804,7 @@ int mfTraceDecode(uint8_t *data_src, int len, bool wantSaveToEmlFile) {
                crypto1_word(traceCrypto1, ar, 1);\r
                crypto1_word(traceCrypto1, 0, 0);\r
                crypto1_word(traceCrypto1, 0, 0);*/\r
-       \r
+\r
                        return 0;\r
                } else {\r
                        traceState = TRACE_ERROR;\r
@@ -793,7 +812,7 @@ int mfTraceDecode(uint8_t *data_src, int len, bool wantSaveToEmlFile) {
                }\r
        break;\r
 \r
-       default: \r
+       default:\r
                traceState = TRACE_ERROR;\r
                return 1;\r
        }\r
@@ -820,3 +839,50 @@ int tryDecryptWord(uint32_t nt, uint32_t ar_enc, uint32_t at_enc, uint8_t *data,
        crypto1_destroy(traceCrypto1);\r
        return 0;\r
 }\r
+\r
+int mfCIdentify()\r
+{\r
+       UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0}};\r
+       SendCommand(&c);\r
+\r
+       UsbCommand resp;\r
+       WaitForResponse(CMD_ACK,&resp);\r
+\r
+       iso14a_card_select_t card;\r
+       memcpy(&card, (iso14a_card_select_t *)resp.d.asBytes, sizeof(iso14a_card_select_t));\r
+\r
+       uint64_t select_status = resp.arg[0];           // 0: couldn't read, 1: OK, with ATS, 2: OK, no ATS, 3: proprietary Anticollision\r
+\r
+       if(select_status != 0) {\r
+               uint8_t rats[] = { 0xE0, 0x80 }; // FSDI=8 (FSD=256), CID=0\r
+               c.arg[0] = ISO14A_RAW | ISO14A_APPEND_CRC | ISO14A_NO_DISCONNECT;\r
+               c.arg[1] = 2;\r
+               c.arg[2] = 0;\r
+               memcpy(c.d.asBytes, rats, 2);\r
+               SendCommand(&c);\r
+               WaitForResponse(CMD_ACK,&resp);\r
+       }\r
+\r
+       c.cmd = CMD_MIFARE_CIDENT;\r
+       c.arg[0] = 0;\r
+       c.arg[1] = 0;\r
+       c.arg[2] = 0;\r
+       SendCommand(&c);\r
+       WaitForResponse(CMD_ACK,&resp);\r
+\r
+       uint8_t isGeneration = resp.arg[0] & 0xff;\r
+       switch( isGeneration ){\r
+               case 1: PrintAndLog("Chinese magic backdoor commands (GEN 1a) detected"); break;\r
+               case 2: PrintAndLog("Chinese magic backdoor command (GEN 1b) detected"); break;\r
+               default: PrintAndLog("No chinese magic backdoor command detected"); break;\r
+       }\r
+\r
+       // disconnect\r
+       c.cmd = CMD_READER_ISO_14443a;\r
+       c.arg[0] = 0;\r
+       c.arg[1] = 0;\r
+       c.arg[2] = 0;\r
+       SendCommand(&c);\r
+\r
+       return (int) isGeneration;\r
+}\r
index c564444285fba1a8a76990c861a7e7616aecf42c..7f9a2b45a785984e0cd5d5b58c68b3a37c789969 100644 (file)
 #include "data.h"\r
 \r
 // mfCSetBlock work flags\r
-#define CSETBLOCK_UID                                  0x01\r
-#define CSETBLOCK_WUPC                                 0x02\r
-#define CSETBLOCK_HALT                                 0x04\r
+#define CSETBLOCK_UID                          0x01\r
+#define CSETBLOCK_WUPC                         0x02\r
+#define CSETBLOCK_HALT                         0x04\r
 #define CSETBLOCK_INIT_FIELD                   0x08\r
 #define CSETBLOCK_RESET_FIELD                  0x10\r
 #define CSETBLOCK_SINGLE_OPER                  0x1F\r
+#define CSETBLOCK_MAGIC_1B                     0x40\r
 \r
 extern char logHexFileName[FILE_PATH_SIZE];\r
 \r
@@ -46,4 +47,6 @@ extern int loadTraceCard(uint8_t *tuid);
 extern int saveTraceCard(void);\r
 extern int tryDecryptWord(uint32_t nt, uint32_t ar_enc, uint32_t at_enc, uint8_t *data, int len);\r
 \r
+extern int mfCIdentify();\r
+\r
 #endif\r
index 66a61fba9005f29555ae38904470e223bfa5dafb..a14c6b78ecf591e7c2c2c4baace1245cb29d64b8 100644 (file)
@@ -92,7 +92,7 @@ function GetCardInfo()
                numSectors = 5\r
        elseif  0x10 == result.sak then -- NXP MIFARE Plus 2k\r
                numSectors = 32\r
-       elseif  0x01 == sak then        -- NXP MIFARE TNP3xxx 1K\r
+       elseif  0x01 == result.sak then -- NXP MIFARE TNP3xxx 1K\r
                numSectors = 16\r
        else\r
                print("I don't know how many sectors there are on this type of card, defaulting to 16")\r
index d2e0fca42b4cab88ae4995575a482a5afe3ca021..880e2c2b04ebfe20cd6d212f82d20837db9e5eb4 100644 (file)
@@ -505,13 +505,14 @@ int DetectASKClock(uint8_t dest[], size_t size, int *clock, int maxErr) {
        return bestStart[best];
 }
 
-int DetectStrongNRZClk(uint8_t *dest, size_t size, int peak, int low){
+int DetectStrongNRZClk(uint8_t *dest, size_t size, int peak, int low, bool *strong) {
        //find shortest transition from high to low
+       *strong = false;
        size_t i = 0;
        size_t transition1 = 0;
        int lowestTransition = 255;
        bool lastWasHigh = false;
-
+       size_t transitionSampleCount = 0;
        //find first valid beginning of a high or low wave
        while ((dest[i] >= peak || dest[i] <= low) && (i < size))
                ++i;
@@ -527,10 +528,17 @@ int DetectStrongNRZClk(uint8_t *dest, size_t size, int peak, int low){
                        lastWasHigh = (dest[i] >= peak);
                        if (i-transition1 < lowestTransition) lowestTransition = i-transition1;
                        transition1 = i;
+               } else if (dest[i] < peak && dest[i] > low) {
+                       transitionSampleCount++;
                }
        }
        if (lowestTransition == 255) lowestTransition = 0;
        if (g_debugMode==2) prnt("DEBUG NRZ: detectstrongNRZclk smallest wave: %d",lowestTransition);
+       // if less than 10% of the samples were not peaks (or 90% were peaks) then we have a strong wave
+       if (transitionSampleCount / size < 10) {
+               *strong = true;
+               lowestTransition = getClosestClock(lowestTransition);
+       }
        return lowestTransition;
 }
 
@@ -550,7 +558,9 @@ int DetectNRZClock(uint8_t dest[], size_t size, int clock, size_t *clockStartIdx
        int peak, low;
        if (getHiLo(dest, loopCnt, &peak, &low, 90, 90) < 1) return 0;
 
-       int lowestTransition = DetectStrongNRZClk(dest, size-20, peak, low);
+       bool strong = false;
+       int lowestTransition = DetectStrongNRZClk(dest, size-20, peak, low, &strong);
+       if (strong) return lowestTransition;
        size_t ii;
        uint8_t clkCnt;
        uint8_t tol = 0;
index ad86886dbc0b69afc29ce453b08ec94be5cd23fb..e2386cd5926fb2c5869d189e88981e317246f806 100644 (file)
@@ -37,4 +37,17 @@ typedef enum ISO14A_COMMAND {
        ISO14A_TOPAZMODE =                      (1 << 8)
 } iso14a_command_t;
 
+typedef struct {
+       uint32_t cuid;
+       uint8_t  sector;
+       uint8_t  keytype;
+       uint32_t nonce;
+       uint32_t ar;
+       uint32_t nr;
+       uint32_t at;
+       uint32_t nonce2;
+       uint32_t ar2;
+       uint32_t nr2;
+} nonces_t;
+
 #endif // _MIFARE_H_
index ede971dc7c9bc4cbf4680fd3e737f4ec1b02cb9a..92d3be720c848f3cd0a1f89db625c691b864d124 100755 (executable)
@@ -1,7 +1,7 @@
 VPATH = ../../common ../../common/crapto1 ../../client
 CC = gcc
 LD = gcc
-CFLAGS = -std=c99 -D_ISOC99_SOURCE -I../../common -I../../client -Wall -O3
+CFLAGS = -std=c99 -D_ISOC99_SOURCE -I../../include -I../../common -I../../client -Wall -O3
 LDFLAGS =
 
 OBJS = crypto1.o crapto1.o parity.o util_posix.o mfkey.o
Impressum, Datenschutz