]> git.zerfleddert.de Git - proxmark3-svn/commitdiff
Merge branch 'master' of https://github.com/Proxmark/proxmark3
authoriceman1001 <iceman@iuse.se>
Tue, 23 Jun 2015 21:02:29 +0000 (23:02 +0200)
committericeman1001 <iceman@iuse.se>
Tue, 23 Jun 2015 21:02:29 +0000 (23:02 +0200)
Conflicts:
armsrc/Makefile
armsrc/iso14443b.c
armsrc/lfops.c
client/cmdhf14b.c
client/cmdhfmfu.c
fpga/fpga_hf.bit
fpga/hi_read_rx_xcorr.v

1  2 
armsrc/epa.c
armsrc/iso14443b.c
armsrc/lfops.c
client/cmddata.c
client/cmdhf14b.c
client/cmdhfmfu.c
client/hid-flasher/usb_cmd.h

diff --combined armsrc/epa.c
index 68061512e3f78745bc0395a4c99c3e9911120374,6bd8692ecaa52d53c7c18ea3364acac26fdb670a..8cc0e4b298f4af877d2d627504d7e007fc0e879c
@@@ -127,7 -127,7 +127,7 @@@ size_t EPA_Parse_CardAccess(uint8_t *da
                              pace_version_info_t *pace_info)
  {
        size_t index = 0;
-       
        while (index <= length - 2) {
                // determine type of element
                // SET or SEQUENCE
                        index += 2 + data[index + 1];
                }
        }
-       
        // TODO: We should check whether we reached the end in error, but for that
        //       we need a better parser (e.g. with states like IN_SET or IN_PACE_INFO)
        return 0;
@@@ -202,7 -202,7 +202,7 @@@ int EPA_Read_CardAccess(uint8_t *buffer
        // we reserve 262 bytes here just to be safe (256-byte APDU + SW + ISO frame)
        uint8_t response_apdu[262];
        int rapdu_length = 0;
-       
        // select the file EF.CardAccess
        rapdu_length = iso14_apdu((uint8_t *)apdu_select_binary_cardaccess,
                                  sizeof(apdu_select_binary_cardaccess),
                Dbprintf("epa - no select cardaccess");
                return -1;
        }
-       
        // read the file
        rapdu_length = iso14_apdu((uint8_t *)apdu_read_binary,
                                  sizeof(apdu_read_binary),
                Dbprintf("epa - no read cardaccess");
                return -1;
        }
-       
        // copy the content into the buffer
        // length of data available: apdu_length - 4 (ISO frame) - 2 (SW)
        size_t to_copy = rapdu_length - 6;
@@@ -243,7 -243,7 +243,7 @@@ static void EPA_PACE_Collect_Nonce_Abor
  {
        // power down the field
        EPA_Finish();
-       
        // send the USB packet
        cmd_send(CMD_ACK,step,func_return,0,0,0);
  }
@@@ -269,7 -269,7 +269,7 @@@ void EPA_PACE_Collect_Nonce(UsbCommand 
  
        // set up communication
        func_return = EPA_Setup();
 -      if (func_return != 0) {
 +      if (func_return != 0) { 
                EPA_PACE_Collect_Nonce_Abort(1, func_return);
                return;
        }
                EPA_PACE_Collect_Nonce_Abort(3, func_return);
                return;
        }
-       
        // initiate the PACE protocol
        // use the CAN for the password since that doesn't change
        func_return = EPA_PACE_MSE_Set_AT(pace_version_info, 2);
-       
        // now get the nonce
        uint8_t nonce[256] = {0};
        uint8_t requested_size = (uint8_t)c->arg[0];
                EPA_PACE_Collect_Nonce_Abort(4, func_return);
                return;
        }
-   
-   // all done, return
+       // all done, return
        EPA_Finish();
-       
        // save received information
        cmd_send(CMD_ACK,0,func_return,0,nonce,func_return);
  }
@@@ -335,7 -335,7 +335,7 @@@ int EPA_PACE_Get_Nonce(uint8_t requeste
               sizeof(apdu_general_authenticate_pace_get_nonce));
        // append Le (requested length + 2 due to tag/length taking 2 bytes) in RAPDU
        apdu[sizeof(apdu_general_authenticate_pace_get_nonce)] = requested_length + 4;
-       
        // send it
        uint8_t response_apdu[262];
        int send_return = iso14_apdu(apdu,
        {
                return -1;
        }
-       
        // if there is no nonce in the RAPDU, return here
        if (send_return < 10)
        {
        }
        // copy the nonce
        memcpy(nonce, response_apdu + 6, nonce_length);
-       
        return nonce_length;
  }
  
diff --combined armsrc/iso14443b.c
index db2c547950040ca44127b402482e39b4cf4ab62c,416c31f93142e9f819393a327ae132497909d9c0..67e4ccddb7d304505413ed5cbb34198859cdb403
@@@ -17,6 -17,7 +17,7 @@@
  #include "iso14443crc.h"
  
  #define RECEIVE_SAMPLES_TIMEOUT 2000
+ #define ISO14443B_DMA_BUFFER_SIZE 256
  
  //=============================================================================
  // An ISO 14443 Type B tag. We listen for commands from the reader, using
@@@ -234,17 -235,17 +235,17 @@@ static RAMFUNC int Handle14443bUartBit(
                                                Uart.posCnt = 0;
                                                Uart.state = STATE_AWAITING_START_BIT;
                                        }
-                               } else if(Uart.shiftReg == 0x000) {
+                               } else if (Uart.shiftReg == 0x000) {
                                        // this is an EOF byte
                                        LED_A_OFF(); // Finished receiving
                                        Uart.state = STATE_UNSYNCD;
                                        if (Uart.byteCnt != 0) {
 -                                              return TRUE;
 +                                      return TRUE;
                                        }
                                } else {
                                        // this is an error
                                        LED_A_OFF();
-                               Uart.state = STATE_UNSYNCD;
+                                       Uart.state = STATE_UNSYNCD;
                                }
                        }
                        break;
@@@ -364,8 -365,8 +365,8 @@@ void SimulateIso14443bTag(void
        for(;;) {
  
                if(!GetIso14443bCommandFromReader(receivedCmd, &len)) {
 -                      Dbprintf("button pressed, received %d commands", cmdsRecvd);
 -                      break;
 +              Dbprintf("button pressed, received %d commands", cmdsRecvd);
 +              break;
                }
  
                if (tracing) {
@@@ -486,8 -487,8 +487,8 @@@ static RAMFUNC int Handle14443bSamplesD
  {
        int v;
  
      // The soft decision on the bit uses an estimate of just the
      // quadrant of the reference angle, not the exact angle.
+ // The soft decision on the bit uses an estimate of just the
+ // quadrant of the reference angle, not the exact angle.
  #define MAKE_SOFT_DECISION() { \
                if(Demod.sumI > 0) { \
                        v = ci; \
                                Demod.sumI = ci;
                                Demod.sumQ = cq;
                                Demod.posCount = 1;
 -                              }
 +                      }
                        break;
  
                case DEMOD_PHASE_REF_TRAINING:
                                if (v > SUBCARRIER_DETECT_THRESHOLD) {
                                        // set the reference phase (will code a logic '1') by averaging over 32 1/fs.
                                        // note: synchronization time > 80 1/fs
 -                                      Demod.sumI += ci;
 -                                      Demod.sumQ += cq;
 +                              Demod.sumI += ci;
 +                              Demod.sumQ += cq;
                                        Demod.posCount++;
                                } else {                // subcarrier lost
 -                                      Demod.state = DEMOD_UNSYNCD;
 +                              Demod.state = DEMOD_UNSYNCD;
                                }
                        } else {
 -                              Demod.state = DEMOD_AWAITING_FALLING_EDGE_OF_SOF;
 +                                      Demod.state = DEMOD_AWAITING_FALLING_EDGE_OF_SOF;
                        }
                        break;
  
                                                LED_C_OFF();
                                                if(s == 0x000) {
                                                        // This is EOF (start, stop and all data bits == '0'
 -                                                      return TRUE;
 +                                              return TRUE;
                                                }
                                        }
                                }
@@@ -717,16 -718,16 +718,16 @@@ static void GetSamplesFor14443bDemod(in
        uint8_t *receivedResponse = BigBuf_malloc(MAX_FRAME_SIZE);
        
        // The DMA buffer, used to stream samples from the FPGA
-       int8_t *dmaBuf = (int8_t*) BigBuf_malloc(DMA_BUFFER_SIZE);
+       int8_t *dmaBuf = (int8_t*) BigBuf_malloc(ISO14443B_DMA_BUFFER_SIZE);
  
        // Set up the demodulator for tag -> reader responses.
        DemodInit(receivedResponse);
  
        // Setup and start DMA.
-       FpgaSetupSscDma((uint8_t*) dmaBuf, DMA_BUFFER_SIZE);
+       FpgaSetupSscDma((uint8_t*) dmaBuf, ISO14443B_DMA_BUFFER_SIZE);
  
        int8_t *upTo = dmaBuf;
-       lastRxCounter = DMA_BUFFER_SIZE;
+       lastRxCounter = ISO14443B_DMA_BUFFER_SIZE;
  
        // Signal field is ON with the appropriate LED:
        LED_D_ON();
                int behindBy = lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR;
                if(behindBy > max) max = behindBy;
  
-               while(((lastRxCounter-AT91C_BASE_PDC_SSC->PDC_RCR) & (DMA_BUFFER_SIZE-1)) > 2) {
+               while(((lastRxCounter-AT91C_BASE_PDC_SSC->PDC_RCR) & (ISO14443B_DMA_BUFFER_SIZE-1)) > 2) {
                        ci = upTo[0];
                        cq = upTo[1];
                        upTo += 2;
-                       if(upTo >= dmaBuf + DMA_BUFFER_SIZE) {
+                       if(upTo >= dmaBuf + ISO14443B_DMA_BUFFER_SIZE) {
                                upTo = dmaBuf;
                                AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) upTo;
-                               AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE;
+                               AT91C_BASE_PDC_SSC->PDC_RNCR = ISO14443B_DMA_BUFFER_SIZE;
                        }
                        lastRxCounter -= 2;
                        if(lastRxCounter <= 0) {
-                               lastRxCounter += DMA_BUFFER_SIZE;
+                               lastRxCounter += ISO14443B_DMA_BUFFER_SIZE;
                        }
  
                        samples += 2;
  
                        if(Handle14443bSamplesDemod(ci, cq)) {
                                gotFrame = TRUE;
-                       break;
+                               break;
 -                      }
                }
 +      }
  
                if(samples > n || gotFrame) {
                        break;
        //Tracing
        if (tracing && Demod.len > 0) {
                uint8_t parity[MAX_PARITY_SIZE];
-               //GetParity(Demod.output, Demod.len, parity);
                LogTrace(Demod.output, Demod.len, 0, 0, parity, FALSE);
        }
  }
@@@ -892,7 -892,6 +892,6 @@@ static void CodeAndTransmit14443bAsRead
        TransmitFor14443b();
        if (tracing) {
                uint8_t parity[MAX_PARITY_SIZE];
-               GetParity(cmd, len, parity);
                LogTrace(cmd,len, 0, 0, parity, TRUE);
        }
  }
@@@ -931,30 -930,25 +930,25 @@@ void ReadSTMemoryIso14443b(uint32_t dwL
        SpinDelay(200);
  
        // First command: wake up the tag using the INITIATE command
-       uint8_t cmd1[] = { 0x06, 0x00, 0x97, 0x5b};
+       uint8_t cmd1[] = {0x06, 0x00, 0x97, 0x5b};
        CodeAndTransmit14443bAsReader(cmd1, sizeof(cmd1));
- //    LED_A_ON();
        GetSamplesFor14443bDemod(RECEIVE_SAMPLES_TIMEOUT, TRUE);
- //    LED_A_OFF();
  
        if (Demod.len == 0) {
                DbpString("No response from tag");
                return;
        } else {
-               Dbprintf("Randomly generated UID from tag (+ 2 byte CRC): %02x %02x %02x",
-               Demod.output[0], Demod.output[1],Demod.output[2]);
+               Dbprintf("Randomly generated Chip ID (+ 2 byte CRC): %02x %02x %02x",
+                               Demod.output[0], Demod.output[1], Demod.output[2]);
        }
        // There is a response, SELECT the uid
        DbpString("Now SELECT tag:");
        cmd1[0] = 0x0E; // 0x0E is SELECT
        cmd1[1] = Demod.output[0];
        ComputeCrc14443(CRC_14443_B, cmd1, 2, &cmd1[2], &cmd1[3]);
        CodeAndTransmit14443bAsReader(cmd1, sizeof(cmd1));
- //    LED_A_ON();
        GetSamplesFor14443bDemod(RECEIVE_SAMPLES_TIMEOUT, TRUE);
- //    LED_A_OFF();
        if (Demod.len != 3) {
                Dbprintf("Expected 3 bytes from tag, got %d", Demod.len);
                return;
                Dbprintf("Bad response to SELECT from Tag, aborting: %02x %02x", cmd1[1], Demod.output[0]);
                return;
        }
        // Tag is now selected,
        // First get the tag's UID:
        cmd1[0] = 0x0B;
        ComputeCrc14443(CRC_14443_B, cmd1, 1 , &cmd1[1], &cmd1[2]);
        CodeAndTransmit14443bAsReader(cmd1, 3); // Only first three bytes for this one
- //    LED_A_ON();
        GetSamplesFor14443bDemod(RECEIVE_SAMPLES_TIMEOUT, TRUE);
- //    LED_A_OFF();
        if (Demod.len != 10) {
                Dbprintf("Expected 10 bytes from tag, got %d", Demod.len);
                return;
        }
        // The check the CRC of the answer (use cmd1 as temporary variable):
        ComputeCrc14443(CRC_14443_B, Demod.output, 8, &cmd1[2], &cmd1[3]);
-    if(cmd1[2] != Demod.output[8] || cmd1[3] != Demod.output[9]) {
+       if(cmd1[2] != Demod.output[8] || cmd1[3] != Demod.output[9]) {
                Dbprintf("CRC Error reading block! Expected: %04x got: %04x",
-               (cmd1[2]<<8)+cmd1[3],
-               (Demod.output[8]<<8)+Demod.output[9]
-               );
+                               (cmd1[2]<<8)+cmd1[3], (Demod.output[8]<<8)+Demod.output[9]);
 -              // Do not return;, let's go on... (we should retry, maybe ?)
 +      // Do not return;, let's go on... (we should retry, maybe ?)
        }
        Dbprintf("Tag UID (64 bits): %08x %08x",
-               (Demod.output[7]<<24) + (Demod.output[6]<<16) + (Demod.output[5]<<8) + Demod.output[4],
-               (Demod.output[3]<<24) + (Demod.output[2]<<16) + (Demod.output[1]<<8) + Demod.output[0]);
+                       (Demod.output[7]<<24) + (Demod.output[6]<<16) + (Demod.output[5]<<8) + Demod.output[4],
+                       (Demod.output[3]<<24) + (Demod.output[2]<<16) + (Demod.output[1]<<8) + Demod.output[0]);
  
        // Now loop to read all 16 blocks, address from 0 to last block
-       Dbprintf("Tag memory dump, block 0 to %d",dwLast);
+       Dbprintf("Tag memory dump, block 0 to %d", dwLast);
        cmd1[0] = 0x08;
        i = 0x00;
        dwLast++;
        for (;;) {
 -              if (i == dwLast) {
 +                 if (i == dwLast) {
                        DbpString("System area block (0xff):");
                        i = 0xff;
                }
                cmd1[1] = i;
                ComputeCrc14443(CRC_14443_B, cmd1, 2, &cmd1[2], &cmd1[3]);
                CodeAndTransmit14443bAsReader(cmd1, sizeof(cmd1));
- //        LED_A_ON();
                GetSamplesFor14443bDemod(RECEIVE_SAMPLES_TIMEOUT, TRUE);
- //        LED_A_OFF();
                if (Demod.len != 6) { // Check if we got an answer from the tag
 -                      DbpString("Expected 6 bytes from tag, got less...");
 -                      return;
 +              DbpString("Expected 6 bytes from tag, got less...");
 +              return;
                }
                // The check the CRC of the answer (use cmd1 as temporary variable):
                ComputeCrc14443(CRC_14443_B, Demod.output, 4, &cmd1[2], &cmd1[3]);
 -              if(cmd1[2] != Demod.output[4] || cmd1[3] != Demod.output[5]) {
 +                      if(cmd1[2] != Demod.output[4] || cmd1[3] != Demod.output[5]) {
-                               Dbprintf("CRC Error reading block! Expected: %04x got: %04x",
-                                       (cmd1[2]<<8)+cmd1[3],
-                                       (Demod.output[4]<<8)+Demod.output[5]
-                               );
+                       Dbprintf("CRC Error reading block! Expected: %04x got: %04x",
+                                       (cmd1[2]<<8)+cmd1[3], (Demod.output[4]<<8)+Demod.output[5]);
 -                      // Do not return;, let's go on... (we should retry, maybe ?)
 +              // Do not return;, let's go on... (we should retry, maybe ?)
                }
                // Now print out the memory location:
                Dbprintf("Address=%02x, Contents=%08x, CRC=%04x", i,
-                       (Demod.output[3]<<24) + (Demod.output[2]<<16) + (Demod.output[1]<<8) + Demod.output[0],
+                               (Demod.output[3]<<24) + (Demod.output[2]<<16) + (Demod.output[1]<<8) + Demod.output[0],
 -                              (Demod.output[4]<<8)+Demod.output[5]);
 -              if (i == 0xff) {
 -                      break;
 -              }
 +                      (Demod.output[4]<<8)+Demod.output[5]
 +              );
 +              if (i == 0xff) break;
                i++;
        }
  }
   * Memory usage for this function, (within BigBuf)
   * Last Received command (reader->tag) - MAX_FRAME_SIZE
   * Last Received command (tag->reader) - MAX_FRAME_SIZE
-  * DMA Buffer - DMA_BUFFER_SIZE
+  * DMA Buffer - ISO14443B_DMA_BUFFER_SIZE
   * Demodulated samples received - all the rest
   */
  void RAMFUNC SnoopIso14443b(void)
        set_tracing(TRUE);
  
        // The DMA buffer, used to stream samples from the FPGA
-       int8_t *dmaBuf = (int8_t*) BigBuf_malloc(DMA_BUFFER_SIZE);
+       int8_t *dmaBuf = (int8_t*) BigBuf_malloc(ISO14443B_DMA_BUFFER_SIZE);
        int lastRxCounter;
        int8_t *upTo;
        int ci, cq;
        Dbprintf("  Trace: %i bytes", BigBuf_max_traceLen());
        Dbprintf("  Reader -> tag: %i bytes", MAX_FRAME_SIZE);
        Dbprintf("  tag -> Reader: %i bytes", MAX_FRAME_SIZE);
-       Dbprintf("  DMA: %i bytes", DMA_BUFFER_SIZE);
+       Dbprintf("  DMA: %i bytes", ISO14443B_DMA_BUFFER_SIZE);
  
        // Signal field is off, no reader signal, no tag signal
        LEDsoff();
        // Setup for the DMA.
        FpgaSetupSsc();
        upTo = dmaBuf;
-       lastRxCounter = DMA_BUFFER_SIZE;
-       FpgaSetupSscDma((uint8_t*) dmaBuf, DMA_BUFFER_SIZE);
+       lastRxCounter = ISO14443B_DMA_BUFFER_SIZE;
+       FpgaSetupSscDma((uint8_t*) dmaBuf, ISO14443B_DMA_BUFFER_SIZE);
        uint8_t parity[MAX_PARITY_SIZE];
++      bool TagIsActive = FALSE;
++      bool ReaderIsActive = FALSE;
 +              
        bool TagIsActive = FALSE;
        bool ReaderIsActive = FALSE;
        
        // And now we loop, receiving samples.
        for(;;) {
                int behindBy = (lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR) &
-                                                               (DMA_BUFFER_SIZE-1);
+                                                               (ISO14443B_DMA_BUFFER_SIZE-1);
                if(behindBy > maxBehindBy) {
                        maxBehindBy = behindBy;
                }
                cq = upTo[1];
                upTo += 2;
                lastRxCounter -= 2;
-               if(upTo >= dmaBuf + DMA_BUFFER_SIZE) {
+               if(upTo >= dmaBuf + ISO14443B_DMA_BUFFER_SIZE) {
                        upTo = dmaBuf;
-                       lastRxCounter += DMA_BUFFER_SIZE;
+                       lastRxCounter += ISO14443B_DMA_BUFFER_SIZE;
                        AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dmaBuf;
-                       AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE;
+                       AT91C_BASE_PDC_SSC->PDC_RNCR = ISO14443B_DMA_BUFFER_SIZE;
+                       WDT_HIT();
+                       if(behindBy > (9*ISO14443B_DMA_BUFFER_SIZE/10)) { // TODO: understand whether we can increase/decrease as we want or not?
+                               Dbprintf("blew circular buffer! behindBy=%d", behindBy);
+                               break;
 +                      WDT_HIT();
 +                      if(behindBy > (9*DMA_BUFFER_SIZE/10)) { // TODO: understand whether we can increase/decrease as we want or not?
 +                              Dbprintf("blew circular buffer! behindBy=%d", behindBy);
 +                              break;
                        }
                        if(!tracing) {
                                DbpString("Reached trace limit");
  
                if (!TagIsActive) {                                                     // no need to try decoding reader data if the tag is sending
                        if(Handle14443bUartBit(ci & 0x01)) {
 -                              if(triggered && tracing) {
 +                      if(triggered && tracing) {
-                                       //GetParity(Uart.output, Uart.byteCnt, parity);
-                               LogTrace(Uart.output,Uart.byteCnt,samples, samples,parity,TRUE);
+                                       LogTrace(Uart.output, Uart.byteCnt, samples, samples, parity, TRUE);
 -                              }
 -                              /* And ready to receive another command. */
 -                              UartReset();
 -                              /* And also reset the demod code, which might have been */
 -                              /* false-triggered by the commands from the reader. */
 -                              DemodReset();
                        }
 +                      /* And ready to receive another command. */
 +                      UartReset();
 +                      /* And also reset the demod code, which might have been */
 +                      /* false-triggered by the commands from the reader. */
 +                      DemodReset();
 +              }
                        if(Handle14443bUartBit(cq & 0x01)) {
 -                              if(triggered && tracing) {
 +                      if(triggered && tracing) {
-                                       //GetParity(Uart.output, Uart.byteCnt, parity);
-                               LogTrace(Uart.output,Uart.byteCnt,samples, samples, parity, TRUE);
+                                       LogTrace(Uart.output, Uart.byteCnt, samples, samples, parity, TRUE);
 -                              }
 -                              /* And ready to receive another command. */
 -                              UartReset();
 -                              /* And also reset the demod code, which might have been */
 -                              /* false-triggered by the commands from the reader. */
 -                              DemodReset();
                        }
 +                      /* And ready to receive another command. */
 +                      UartReset();
 +                      /* And also reset the demod code, which might have been */
 +                      /* false-triggered by the commands from the reader. */
 +                      DemodReset();
 +              }
                        ReaderIsActive = (Uart.state > STATE_GOT_FALLING_EDGE_OF_SOF);
                }
  
                if(!ReaderIsActive) {                                           // no need to try decoding tag data if the reader is sending - and we cannot afford the time
                        if(Handle14443bSamplesDemod(ci | 0x01, cq | 0x01)) {
  
 -                              //Use samples as a time measurement
 -                              if(tracing)
 -                              {
 -                                      uint8_t parity[MAX_PARITY_SIZE];
 +                      //Use samples as a time measurement
 +                      if(tracing)
 +                      {
 +                              uint8_t parity[MAX_PARITY_SIZE];
-                                       //GetParity(Demod.output, Demod.len, parity);
-                               LogTrace(Demod.output, Demod.len,samples, samples, parity, FALSE);
+                                       LogTrace(Demod.output, Demod.len, samples, samples, parity, FALSE);
 -                              }
 -                              triggered = TRUE;
 -
 -                              // And ready to receive another response.
 -                              DemodReset();
                        }
 +                      triggered = TRUE;
 +
 +                      // And ready to receive another response.
 +                      DemodReset();
 +              }
                        TagIsActive = (Demod.state > DEMOD_GOT_FALLING_EDGE_OF_SOF);
                }
  
@@@ -1217,30 -1200,14 +1206,14 @@@ void SendRawCommand14443B(uint32_t data
        SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
        FpgaSetupSsc();
  
-               set_tracing(TRUE);
+       set_tracing(TRUE);
        
- /*    if(!powerfield) {
-               // Make sure that we start from off, since the tags are stateful;
-               // confusing things will happen if we don't reset them between reads.
-               FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
-               LED_D_OFF();
-               SpinDelay(200);
-       }
-  */
-       // if(!GETBIT(GPIO_LED_D))      {       // if field is off
-               // FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ);
-               // // Signal field is on with the appropriate LED
-               // LED_D_ON();
-               // SpinDelay(200);
-       // }
        CodeAndTransmit14443bAsReader(data, datalen);
  
        if(recv) {
                GetSamplesFor14443bDemod(RECEIVE_SAMPLES_TIMEOUT, TRUE);
-               uint16_t iLen = MIN(Demod.len,USB_CMD_DATA_SIZE);
-               cmd_send(CMD_ACK,iLen,0,0,Demod.output,iLen);
+               uint16_t iLen = MIN(Demod.len, USB_CMD_DATA_SIZE);
+               cmd_send(CMD_ACK, iLen, 0, 0, Demod.output, iLen);
        }
        
        if(!powerfield) {
diff --combined armsrc/lfops.c
index c26d063b847fb1facdaea0b5ad714ca8249ff73a,7e53d4a566173d97301f9e56ee1e5ad01a1ca15e..1b3e8e30061bdf1c79427b1b0d8123f8385593d8
@@@ -379,7 -379,7 +379,7 @@@ void WriteTItag(uint32_t idhi, uint32_
        AcquireTiType();
  
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
 -      DbpString("Now use tiread to check");
 +      DbpString("Now use 'lf ti read' to check");
  }
  
  void SimulateTagLowFrequency(int period, int gap, int ledcontrol)
@@@ -756,7 -756,7 +756,7 @@@ void CmdHIDdemodFSK(int findone, int *h
  {
        uint8_t *dest = BigBuf_get_addr();
        //const size_t sizeOfBigBuff = BigBuf_max_traceLen();
 -      size_t size; 
 +      size_t size = 0
        uint32_t hi2=0, hi=0, lo=0;
        int idx=0;
        // Configure to go in 125Khz listen mode
@@@ -866,24 -866,24 +866,24 @@@ void CmdEM410xdemod(int findone, int *h
  
                if (errCnt<0) continue;
        
 -              errCnt = Em410xDecode(dest, &size, &idx, &hi, &lo);
 -              if (errCnt){
 -                      if (size>64){
 -                              Dbprintf("EM XL TAG ID: %06x%08x%08x - (%05d_%03d_%08d)",
 -                                hi,
 -                                (uint32_t)(lo>>32),
 -                                (uint32_t)lo,
 -                                (uint32_t)(lo&0xFFFF),
 -                                (uint32_t)((lo>>16LL) & 0xFF),
 -                                (uint32_t)(lo & 0xFFFFFF));
 -                      } else {
 -                              Dbprintf("EM TAG ID: %02x%08x - (%05d_%03d_%08d)",
 -                                (uint32_t)(lo>>32),
 -                                (uint32_t)lo,
 -                                (uint32_t)(lo&0xFFFF),
 -                                (uint32_t)((lo>>16LL) & 0xFF),
 -                                (uint32_t)(lo & 0xFFFFFF));
 -                      }
 +                      errCnt = Em410xDecode(dest, &size, &idx, &hi, &lo);
 +                      if (errCnt){
 +                              if (size>64){
 +                                      Dbprintf("EM XL TAG ID: %06x%08x%08x - (%05d_%03d_%08d)",
 +                                        hi,
 +                                        (uint32_t)(lo>>32),
 +                                        (uint32_t)lo,
 +                                        (uint32_t)(lo&0xFFFF),
 +                                        (uint32_t)((lo>>16LL) & 0xFF),
 +                                        (uint32_t)(lo & 0xFFFFFF));
 +                              } else {
 +                                      Dbprintf("EM TAG ID: %02x%08x - (%05d_%03d_%08d)",
 +                                        (uint32_t)(lo>>32),
 +                                        (uint32_t)lo,
 +                                        (uint32_t)(lo&0xFFFF),
 +                                        (uint32_t)((lo>>16LL) & 0xFF),
 +                                        (uint32_t)(lo & 0xFFFFFF));
 +                              }
  
                        if (findone){
                                if (ledcontrol) LED_A_OFF();
@@@ -908,8 -908,6 +908,8 @@@ void CmdIOdemodFSK(int findone, int *hi
        uint8_t version=0;
        uint8_t facilitycode=0;
        uint16_t number=0;
 +      uint8_t crc = 0;
 +      uint16_t calccrc = 0;
        // Configure to go in 125Khz listen mode
        LFSetupFPGAForADC(95, true);
  
                WDT_HIT();
                idx = IOdemodFSK(dest, BigBuf_max_traceLen());
                if (idx<0) continue;
 -              //valid tag found
 -
 -              //Index map
 -              //0           10          20          30          40          50          60
 -              //|           |           |           |           |           |           |
 -              //01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23
 -              //-----------------------------------------------------------------------------
 -              //00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 ???????? 11
 -              //
 -              //XSF(version)facility:codeone+codetwo
 -              //Handle the data
 -              if(findone){ //only print binary if we are doing one
 -                      Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx],   dest[idx+1],   dest[idx+2],dest[idx+3],dest[idx+4],dest[idx+5],dest[idx+6],dest[idx+7],dest[idx+8]);
 -                      Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+9], dest[idx+10],dest[idx+11],dest[idx+12],dest[idx+13],dest[idx+14],dest[idx+15],dest[idx+16],dest[idx+17]);
 -                      Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+18],dest[idx+19],dest[idx+20],dest[idx+21],dest[idx+22],dest[idx+23],dest[idx+24],dest[idx+25],dest[idx+26]);
 -                      Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+27],dest[idx+28],dest[idx+29],dest[idx+30],dest[idx+31],dest[idx+32],dest[idx+33],dest[idx+34],dest[idx+35]);
 -                      Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+36],dest[idx+37],dest[idx+38],dest[idx+39],dest[idx+40],dest[idx+41],dest[idx+42],dest[idx+43],dest[idx+44]);
 -                      Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+45],dest[idx+46],dest[idx+47],dest[idx+48],dest[idx+49],dest[idx+50],dest[idx+51],dest[idx+52],dest[idx+53]);
 -                      Dbprintf("%d%d%d%d%d%d%d%d %d%d",dest[idx+54],dest[idx+55],dest[idx+56],dest[idx+57],dest[idx+58],dest[idx+59],dest[idx+60],dest[idx+61],dest[idx+62],dest[idx+63]);
 -              }
 -              code = bytebits_to_byte(dest+idx,32);
 -              code2 = bytebits_to_byte(dest+idx+32,32);
 -              version = bytebits_to_byte(dest+idx+27,8); //14,4
 +                      //valid tag found
 +
 +                      //Index map
 +                      //0           10          20          30          40          50          60
 +                      //|           |           |           |           |           |           |
 +                      //01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23
 +                      //-----------------------------------------------------------------------------
 +            //00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 checksum 11
 +                      //
 +                      //Checksum:  
 +                      //00000000 0 11110000 1 11100000 1 00000001 1 00000011 1 10110110 1 01110101 11
 +                      //preamble      F0         E0         01         03         B6         75
 +                      // How to calc checksum,
 +                      // http://www.proxmark.org/forum/viewtopic.php?id=364&p=6
 +                      //   F0 + E0 + 01 + 03 + B6 = 28A
 +                      //   28A & FF = 8A
 +                      //   FF - 8A = 75
 +                      // Checksum: 0x75
 +                      //XSF(version)facility:codeone+codetwo
 +                      //Handle the data
 +                      if(findone){ //only print binary if we are doing one
 +                              Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx],   dest[idx+1],   dest[idx+2],dest[idx+3],dest[idx+4],dest[idx+5],dest[idx+6],dest[idx+7],dest[idx+8]);
 +                              Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+9], dest[idx+10],dest[idx+11],dest[idx+12],dest[idx+13],dest[idx+14],dest[idx+15],dest[idx+16],dest[idx+17]);
 +                              Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+18],dest[idx+19],dest[idx+20],dest[idx+21],dest[idx+22],dest[idx+23],dest[idx+24],dest[idx+25],dest[idx+26]);
 +                              Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+27],dest[idx+28],dest[idx+29],dest[idx+30],dest[idx+31],dest[idx+32],dest[idx+33],dest[idx+34],dest[idx+35]);
 +                              Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+36],dest[idx+37],dest[idx+38],dest[idx+39],dest[idx+40],dest[idx+41],dest[idx+42],dest[idx+43],dest[idx+44]);
 +                              Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+45],dest[idx+46],dest[idx+47],dest[idx+48],dest[idx+49],dest[idx+50],dest[idx+51],dest[idx+52],dest[idx+53]);
 +                              Dbprintf("%d%d%d%d%d%d%d%d %d%d",dest[idx+54],dest[idx+55],dest[idx+56],dest[idx+57],dest[idx+58],dest[idx+59],dest[idx+60],dest[idx+61],dest[idx+62],dest[idx+63]);
 +                      }
 +                      code = bytebits_to_byte(dest+idx,32);
 +                      code2 = bytebits_to_byte(dest+idx+32,32);
 +                      version = bytebits_to_byte(dest+idx+27,8); //14,4
                facilitycode = bytebits_to_byte(dest+idx+18,8);
 -              number = (bytebits_to_byte(dest+idx+36,8)<<8)|(bytebits_to_byte(dest+idx+45,8)); //36,9
 -
 -              Dbprintf("XSF(%02d)%02x:%05d (%08x%08x)",version,facilitycode,number,code,code2);
 -              // if we're only looking for one tag
 -              if (findone){
 -                      if (ledcontrol) LED_A_OFF();
 -                      //LED_A_OFF();
 -                      *high=code;
 -                      *low=code2;
 -                      return;
 -              }
 -              code=code2=0;
 -              version=facilitycode=0;
 -              number=0;
 -              idx=0;
 +                      number = (bytebits_to_byte(dest+idx+36,8)<<8)|(bytebits_to_byte(dest+idx+45,8)); //36,9
 +
 +                      crc = bytebits_to_byte(dest+idx+54,8);
 +                      for (uint8_t i=1; i<6; ++i)
 +                              calccrc += bytebits_to_byte(dest+idx+9*i,8);
 +                      calccrc &= 0xff;
 +                      calccrc = 0xff - calccrc;
 +                      
 +                      char *crcStr = (crc == calccrc) ? "ok":"!crc";
 +
 +            Dbprintf("IO Prox XSF(%02d)%02x:%05d (%08x%08x)  [%02x %s]",version,facilitycode,number,code,code2, crc, crcStr);
 +                      // if we're only looking for one tag
 +                      if (findone){
 +                              if (ledcontrol) LED_A_OFF();
 +                              //LED_A_OFF();
 +                              *high=code;
 +                              *low=code2;
 +                              return;
 +                      }
 +                      code=code2=0;
 +                      version=facilitycode=0;
 +                      number=0;
 +                      idx=0;
  
                WDT_HIT();
        }
   * To compensate antenna falling times shorten the write times
   * and enlarge the gap ones.
   */
- #define START_GAP 31*8 // was 250 // SPEC:   8 - 50fc [15fc]
- #define WRITE_GAP 20*8 // was 160 // SPEC:   8 - 20fc [10fc]
- #define WRITE_0   18*8 // was 144 // SPEC:  16 - 32fc [24fc]  192
- #define WRITE_1   50*8 // was 400 // SPEC:  48 - 64fc [56fc]  432 for T55x7; 448 for E5550
+ #define START_GAP 31*8 // was 250 // SPEC:  1*8 to 50*8 - typ 15*8 (or 15fc)
+ #define WRITE_GAP 20*8 // was 160 // SPEC:  1*8 to 20*8 - typ 10*8 (or 10fc)
+ #define WRITE_0   18*8 // was 144 // SPEC: 16*8 to 32*8 - typ 24*8 (or 24fc)
+ #define WRITE_1   50*8 // was 400 // SPEC: 48*8 to 64*8 - typ 56*8 (or 56fc)  432 for T55x7; 448 for E5550
  
 +//  VALUES TAKEN FROM EM4x function: SendForward
 +//  START_GAP = 440;       (55*8) cycles at 125Khz (8us = 1cycle)
 +//  WRITE_GAP = 128;       (16*8)
 +//  WRITE_1   = 256 32*8;  (32*8) 
 +
 +//  These timings work for 4469/4269/4305 (with the 55*8 above)
 +//  WRITE_0 = 23*8 , 9*8  SpinDelayUs(23*8); 
 +
 +// Sam7s has several timers, we will use the source TIMER_CLOCK1 (aka AT91C_TC_CLKS_TIMER_DIV1_CLOCK)
 +// TIMER_CLOCK1 = MCK/2, MCK is running at 48 MHz, Timer is running at 48/2 = 24 MHz
 +// Hitag units (T0) have duration of 8 microseconds (us), which is 1/125000 per second (carrier)
 +// T0 = TIMER_CLOCK1 / 125000 = 192
 +// 1 Cycle = 8 microseconds(us)
 +
  #define T55xx_SAMPLES_SIZE      12000 // 32 x 32 x 10  (32 bit times numofblock (7), times clock skip..)
  
  // Write one bit to card
@@@ -1070,7 -1037,7 +1070,7 @@@ void T55xxWriteBit(int bit
        FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
        FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
        FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
 -      if (bit == 0)
 +      if (!bit)
                SpinDelayUs(WRITE_0);
        else
                SpinDelayUs(WRITE_1);
@@@ -1524,16 -1491,10 +1524,16 @@@ void CopyIndala224toT55x7(int uid1, in
  #define max(x,y) ( x<y ? y:x)
  
  int DemodPCF7931(uint8_t **outBlocks) {
 -      uint8_t BitStream[256];
 -      uint8_t Blocks[8][16];
 -      uint8_t *GraphBuffer = BigBuf_get_addr();
 +
 +    uint8_t bits[256] = {0x00};
 +      uint8_t blocks[8][16];
 +    uint8_t *dest = BigBuf_get_addr();
 +    
        int GraphTraceLen = BigBuf_max_traceLen();
 +      if (  GraphTraceLen > 18000 )
 +              GraphTraceLen = 18000;
 +      
 +      
        int i, j, lastval, bitidx, half_switch;
        int clock = 64;
        int tolerance = clock / 8;
        uint8_t dir;
  
        LFSetupFPGAForADC(95, true);
 -      DoAcquisition_default(0, 0);
 -
 +      DoAcquisition_default(0, true);
  
        lmin = 64;
        lmax = 192;
        i = 2;
  
        /* Find first local max/min */
 -      if(GraphBuffer[1] > GraphBuffer[0]) {
 +    if(dest[1] > dest[0]) {
                while(i < GraphTraceLen) {
 -                      if( !(GraphBuffer[i] > GraphBuffer[i-1]) && GraphBuffer[i] > lmax)
 +            if( !(dest[i] > dest[i-1]) && dest[i] > lmax)
                                break;
                        i++;
                }
        }
        else {
                while(i < GraphTraceLen) {
 -                      if( !(GraphBuffer[i] < GraphBuffer[i-1]) && GraphBuffer[i] < lmin)
 +            if( !(dest[i] < dest[i-1]) && dest[i] < lmin)
                                break;
                        i++;
                }
  
        for (bitidx = 0; i < GraphTraceLen; i++)
        {
 -              if ( (GraphBuffer[i-1] > GraphBuffer[i] && dir == 1 && GraphBuffer[i] > lmax) || (GraphBuffer[i-1] < GraphBuffer[i] && dir == 0 && GraphBuffer[i] < lmin))
 +        if ( (dest[i-1] > dest[i] && dir == 1 && dest[i] > lmax) || (dest[i-1] < dest[i] && dir == 0 && dest[i] < lmin))
                {
                        lc = i - lastval;
                        lastval = i;
                                        block_done = 1;
                                }
                                else if(half_switch == 1) {
 -                                      BitStream[bitidx++] = 0;
 +                    bits[bitidx++] = 0;
                                        half_switch = 0;
                                }
                                else
                                        half_switch++;
                        } else if (abs(lc-clock) < tolerance) {
                                // 64TO
 -                              BitStream[bitidx++] = 1;
 +                bits[bitidx++] = 1;
                        } else {
                                // Error
                                warnings++;
                        if(block_done == 1) {
                                if(bitidx == 128) {
                                        for(j=0; j<16; j++) {
 -                                              Blocks[num_blocks][j] = 128*BitStream[j*8+7]+
 -                                                              64*BitStream[j*8+6]+
 -                                                              32*BitStream[j*8+5]+
 -                                                              16*BitStream[j*8+4]+
 -                                                              8*BitStream[j*8+3]+
 -                                                              4*BitStream[j*8+2]+
 -                                                              2*BitStream[j*8+1]+
 -                                                              BitStream[j*8];
 +                        blocks[num_blocks][j] = 128*bits[j*8+7]+
 +                                64*bits[j*8+6]+
 +                                32*bits[j*8+5]+
 +                                16*bits[j*8+4]+
 +                                8*bits[j*8+3]+
 +                                4*bits[j*8+2]+
 +                                2*bits[j*8+1]+
 +                                bits[j*8];
 +                                              
                                        }
                                        num_blocks++;
                                }
                                half_switch = 0;
                        }
                        if(i < GraphTraceLen)
 -                      {
 -                              if (GraphBuffer[i-1] > GraphBuffer[i]) dir=0;
 -                              else dir = 1;
 -                      }
 +                dir =(dest[i-1] > dest[i]) ? 0 : 1;
                }
                if(bitidx==255)
                        bitidx=0;
                warnings = 0;
                if(num_blocks == 4) break;
        }
 -      memcpy(outBlocks, Blocks, 16*num_blocks);
 +    memcpy(outBlocks, blocks, 16*num_blocks);
        return num_blocks;
  }
  
@@@ -1948,14 -1912,9 +1948,14 @@@ void EM4xLogin(uint32_t Password) 
  
  void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode) {
  
 -      uint8_t fwd_bit_count;
        uint8_t *dest = BigBuf_get_addr();
 -      int m=0, i=0;
 +      uint16_t bufferlength = BigBuf_max_traceLen();
 +      uint32_t i = 0;
 +
 +      // Clear destination buffer before sending the command  0x80 = average.
 +      memset(dest, 0x80, bufferlength);
 +      
 +    uint8_t fwd_bit_count;
  
        //If password mode do login
        if (PwdMode == 1) EM4xLogin(Pwd);
        fwd_bit_count = Prepare_Cmd( FWD_CMD_READ );
        fwd_bit_count += Prepare_Addr( Address );
  
 -      m = BigBuf_max_traceLen();
 -      // Clear destination buffer before sending the command
 -      memset(dest, 128, m);
        // Connect the A/D to the peak-detected low-frequency path.
        SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
        // Now set up the SSC to get the ADC samples that are now streaming at us.
                }
                if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
                        dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
 -                      i++;
 -                      if (i >= m) break;
 +                      ++i;
 +                      if (i >= bufferlength) break;
                }
        }
 +  
 +      cmd_send(CMD_ACK,0,0,0,0,0);
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
        LED_D_OFF();
  }
diff --combined client/cmddata.c
index bc88d883d636f2eb1df7759031217ae704ba285b,bec1b5aa3f4d4394f011394fa61edca5b9a06767..4eca030db416480829f45852e30df8ebccfbfd74
@@@ -500,9 -500,10 +500,9 @@@ int ASKbiphaseDemod(const char *Cmd, bo
        //ask raw demod GraphBuffer first
        int offset=0, clk=0, invert=0, maxErr=0;
        sscanf(Cmd, "%i %i %i %i", &offset, &clk, &invert, &maxErr);
 -
 -      uint8_t BitStream[MAX_DEMOD_BUF_LEN];     
 +      
 +      uint8_t BitStream[MAX_DEMOD_BUF_LEN];
        size_t size = getFromGraphBuf(BitStream);         
 -      //invert here inverts the ask raw demoded bits which has no effect on the demod, but we need the pointer
        int errCnt = askdemod(BitStream, &size, &clk, &invert, maxErr, 0, 0);  
        if ( errCnt < 0 || errCnt > maxErr ) {   
                if (g_debugMode) PrintAndLog("DEBUG: no data or error found %d, clock: %d", errCnt, clk);  
@@@ -1461,17 -1462,6 +1461,17 @@@ int CmdFSKdemodPyramid(const char *Cmd
  // NATIONAL CODE, ICAR database
  // COUNTRY CODE (ISO3166) or http://cms.abvma.ca/uploads/ManufacturersISOsandCountryCodes.pdf
  // FLAG (animal/non-animal)
 +/*
 +38 IDbits   
 +10 country code 
 +1 extra app bit
 +14 reserved bits
 +1 animal bit
 +16 ccitt CRC chksum over 64bit ID CODE.
 +24 appli bits.
 +
 +-- sample: 985121004515220  [ 37FF65B88EF94 ]
 +*/
  int CmdFDXBdemodBI(const char *Cmd){
  
        int invert = 1;
                if (g_debugMode) PrintAndLog("Error BiphaseRawDecode: %d", errCnt);
                return 0;
        } 
 -
 +      
        int preambleIndex = FDXBdemodBI(BitStream, &size);
        if (preambleIndex < 0){
                if (g_debugMode) PrintAndLog("Error FDXBDemod , no startmarker found :: %d",preambleIndex);
                return 0;
        }
 -
 +      
        setDemodBuf(BitStream, 128, preambleIndex);
  
        // remove but don't verify parity. (pType = 2)
@@@ -1561,7 -1551,7 +1561,7 @@@ int PSKDemod(const char *Cmd, bool verb
        }
        uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
        size_t BitLen = getFromGraphBuf(BitStream);
-       if (BitLen==0) return -1;
+       if (BitLen==0) return 0;
        uint8_t carrier=countFC(BitStream, BitLen, 0);
        if (carrier!=2 && carrier!=4 && carrier!=8){
                //invalid carrier
@@@ -1957,7 -1947,7 +1957,7 @@@ typedef struct 
        uint8_t * buffer;
        uint32_t numbits;
        uint32_t position;
 -}BitstreamOut;
 +} BitstreamOut;
  
  bool _headBit( BitstreamOut *stream)
  {
diff --combined client/cmdhf14b.c
index 0144111e72db2a48334ceff8ff3c47c8d743f9e5,496267cd47a55da826aadb888d5516cddb474db8..f9b1313b368922c6a30ae0dba15baa6169ee590a
@@@ -22,7 -22,6 +22,7 @@@
  #include "cmdparser.h"
  #include "cmdhf14b.h"
  #include "cmdmain.h"
 +#include "cmdhf14a.h"
  
  static int CmdHelp(const char *Cmd);
  
@@@ -35,18 -34,16 +35,16 @@@ int CmdHF14BList(const char *Cmd
  
  int CmdHF14BSim(const char *Cmd)
  {
-       UsbCommand c={CMD_SIMULATE_TAG_ISO_14443B};
-       clearCommandBuffer();
+   UsbCommand c={CMD_SIMULATE_TAG_ISO_14443B};
 -  SendCommand(&c);
 -  return 0;
 +      SendCommand(&c);
 +      return 0;
  }
  
  int CmdHF14BSnoop(const char *Cmd)
  {
-       UsbCommand c = {CMD_SNOOP_ISO_14443B};
-       clearCommandBuffer();
+   UsbCommand c = {CMD_SNOOP_ISO_14443B};
 -  SendCommand(&c);
 -  return 0;
 +      SendCommand(&c);
 +      return 0;
  }
  
  /* New command to read the contents of a SRI512 tag
   */
  int CmdSri512Read(const char *Cmd)
  {
 -  UsbCommand c = {CMD_READ_SRI512_TAG, {strtol(Cmd, NULL, 0), 0, 0}};
 -  SendCommand(&c);
 -  return 0;
 +      UsbCommand c = {CMD_READ_SRI512_TAG, {strtol(Cmd, NULL, 0), 0, 0}};
 +      clearCommandBuffer();
 +      SendCommand(&c);
 +      return 0;
  }
  
  /* New command to read the contents of a SRIX4K tag
   */
  int CmdSrix4kRead(const char *Cmd)
  {
 -  UsbCommand c = {CMD_READ_SRIX4K_TAG, {strtol(Cmd, NULL, 0), 0, 0}};
 -  SendCommand(&c);
 -  return 0;
 +      UsbCommand c = {CMD_READ_SRIX4K_TAG, {strtol(Cmd, NULL, 0), 0, 0}};
 +      clearCommandBuffer();
 +      SendCommand(&c);
 +      return 0;
 +}
 +
 +int rawClose(void){
 +      UsbCommand resp;
 +      UsbCommand c = {CMD_ISO_14443B_COMMAND, {0, 0, 0}};
 +      clearCommandBuffer();
 +      SendCommand(&c);
 +      if (!WaitForResponseTimeout(CMD_ACK,&resp,1000)) {
 +              return 0;
 +      }
 +      return 0;       
  }
  
 -int CmdHF14BCmdRaw (const char *cmd) {
 -    UsbCommand resp;
 -    uint8_t *recv;
 -    UsbCommand c = {CMD_ISO_14443B_COMMAND, {0, 0, 0}}; // len,recv?
 -    uint8_t reply=1;
 -    uint8_t crc=0;
 -    uint8_t power=0;
 +int HF14BCmdRaw(bool reply, bool *crc, bool power, uint8_t *data, uint8_t *datalen, bool verbose){
 +      UsbCommand resp;
 +      UsbCommand c = {CMD_ISO_14443B_COMMAND, {0, 0, 0}}; // len,recv,power
 +      if(*crc)
 +      {
 +              uint8_t first, second;
 +              ComputeCrc14443(CRC_14443_B, data, *datalen, &first, &second);
 +              data[*datalen] = first;
 +              data[*datalen + 1] = second;
 +              *datalen += 2;
 +      }
 +
 +      c.arg[0] = *datalen;
 +      c.arg[1] = reply;
 +      c.arg[2] = power;
 +      memcpy(c.d.asBytes,data,*datalen);
 +      clearCommandBuffer();
 +      SendCommand(&c);
 +
 +      if (!reply) return 1; 
 +
 +      if (!WaitForResponseTimeout(CMD_ACK,&resp,1000)) {
 +              if (verbose) PrintAndLog("timeout while waiting for reply.");
 +                      return 0;
 +              }
 +              *datalen = resp.arg[0];
 +              if (verbose) PrintAndLog("received %u octets", *datalen);
 +              if(*datalen<2) return 0;
 +
 +              memcpy(data, resp.d.asBytes, *datalen);
 +              if (verbose) PrintAndLog("%s", sprint_hex(data, *datalen));
 +
 +              uint8_t first, second;
 +              ComputeCrc14443(CRC_14443_B, data, *datalen-2, &first, &second);
 +              if(data[*datalen-2] == first && data[*datalen-1] == second) {
 +                      if (verbose) PrintAndLog("CRC OK");
 +                      *crc = true;
 +              } else {
 +                      if (verbose) PrintAndLog("CRC failed");
 +                      *crc = false;
 +              }
 +      return 1;
 +}
 +
 +int CmdHF14BCmdRaw (const char *Cmd) {
 +    bool reply = true;
 +    bool crc = false;
 +      bool power = false;
      char buf[5]="";
 -    int i=0;
      uint8_t data[100] = {0x00};
 -    unsigned int datalen=0, temp;
 -    char *hexout;
 -    
 -    if (strlen(cmd)<3) {
 +    uint8_t datalen = 0;
 +    unsigned int temp;
 +    int i = 0;
 +    if (strlen(Cmd)<3) {
          PrintAndLog("Usage: hf 14b raw [-r] [-c] [-p] <0A 0B 0C ... hex>");
          PrintAndLog("       -r    do not read response");
          PrintAndLog("       -c    calculate and append CRC");
      }
  
      // strip
 -    while (*cmd==' ' || *cmd=='\t') cmd++;
 +    while (*Cmd==' ' || *Cmd=='\t') Cmd++;
      
 -    while (cmd[i]!='\0') {
 -        if (cmd[i]==' ' || cmd[i]=='\t') { i++; continue; }
 -        if (cmd[i]=='-') {
 -            switch (cmd[i+1]) {
 +    while (Cmd[i]!='\0') {
 +        if (Cmd[i]==' ' || Cmd[i]=='\t') { i++; continue; }
 +        if (Cmd[i]=='-') {
 +            switch (Cmd[i+1]) {
                  case 'r': 
                  case 'R': 
 -                    reply=0;
 +                    reply = false;
                      break;
                  case 'c':
                  case 'C':                
 -                    crc=1;
 +                    crc = true;
                      break;
                  case 'p': 
                  case 'P': 
 -                    power=1;
 +                                      power = true;
                      break;
                  default:
                      PrintAndLog("Invalid option");
              i+=2;
              continue;
          }
 -        if ((cmd[i]>='0' && cmd[i]<='9') ||
 -            (cmd[i]>='a' && cmd[i]<='f') ||
 -            (cmd[i]>='A' && cmd[i]<='F') ) {
 +        if ((Cmd[i]>='0' && Cmd[i]<='9') ||
 +            (Cmd[i]>='a' && Cmd[i]<='f') ||
 +            (Cmd[i]>='A' && Cmd[i]<='F') ) {
              buf[strlen(buf)+1]=0;
 -            buf[strlen(buf)]=cmd[i];
 +            buf[strlen(buf)]=Cmd[i];
              i++;
              
              if (strlen(buf)>=2) {
                  sscanf(buf,"%x",&temp);
 -                data[datalen]=(uint8_t)(temp & 0xff);
 -                datalen++;
 +                data[datalen++]=(uint8_t)(temp & 0xff);
                  *buf=0;
              }
              continue;
        PrintAndLog("Missing data input");
        return 0;
      }
 -    if(crc)
 -    {
 -        uint8_t first, second;
 -        ComputeCrc14443(CRC_14443_B, data, datalen, &first, &second);
 -        data[datalen++] = first;
 -        data[datalen++] = second;
 -    }
 +
 +      return HF14BCmdRaw(reply, &crc, power, data, &datalen, true);
 +}
 +
 +static void print_atqb_resp(uint8_t *data){
 +      PrintAndLog ("           UID: %s", sprint_hex(data+1,4));
 +      PrintAndLog ("      App Data: %s", sprint_hex(data+5,4));
 +      PrintAndLog ("      Protocol: %s", sprint_hex(data+9,3));
 +      uint8_t BitRate = data[9];
 +      if (!BitRate) PrintAndLog ("      Bit Rate: 106 kbit/s only PICC <-> PCD");
 +      if (BitRate & 0x10)     PrintAndLog ("      Bit Rate: 212 kbit/s PICC -> PCD supported");
 +      if (BitRate & 0x20)     PrintAndLog ("      Bit Rate: 424 kbit/s PICC -> PCD supported"); 
 +      if (BitRate & 0x40)     PrintAndLog ("      Bit Rate: 847 kbit/s PICC -> PCD supported"); 
 +      if (BitRate & 0x01)     PrintAndLog ("      Bit Rate: 212 kbit/s PICC <- PCD supported");
 +      if (BitRate & 0x02)     PrintAndLog ("      Bit Rate: 424 kbit/s PICC <- PCD supported"); 
 +      if (BitRate & 0x04)     PrintAndLog ("      Bit Rate: 847 kbit/s PICC <- PCD supported"); 
 +      if (BitRate & 0x80)     PrintAndLog ("                Same bit rate <-> required");
 +
 +      uint16_t maxFrame = data[10]>>4;
 +      if (maxFrame < 5)               maxFrame = 8 * maxFrame + 16;
 +      else if (maxFrame == 5) maxFrame = 64;
 +      else if (maxFrame == 6) maxFrame = 96;
 +      else if (maxFrame == 7) maxFrame = 128;
 +      else if (maxFrame == 8) maxFrame = 256;
 +      else maxFrame = 257;
 +
 +      PrintAndLog ("Max Frame Size: %d%s", maxFrame, (maxFrame == 257) ? "+ RFU" : "");
 +
 +      uint8_t protocolT = data[10] & 0xF;
 +      PrintAndLog (" Protocol Type: Protocol is %scompliant with ISO/IEC 14443-4",(protocolT) ? "" : "not " );
 +      PrintAndLog ("Frame Wait Int: %d", data[11]>>4);
 +      PrintAndLog (" App Data Code: Application is %s",(data[11]&4) ? "Standard" : "Proprietary");
 +      PrintAndLog (" Frame Options: NAD is %ssupported",(data[11]&2) ? "" : "not ");
 +      PrintAndLog (" Frame Options: CID is %ssupported",(data[11]&1) ? "" : "not ");
 +
 +      return;
 +}
 +
 +char *get_ST_Chip_Model(uint8_t data){
 +      static char model[20];
 +      char *retStr = model;
 +      memset(model,0, sizeof(model));
 +
 +      switch (data) {
 +              case 0x0: sprintf(retStr, "SRIX4K (Special)"); break;
 +              case 0x2: sprintf(retStr, "SR176"); break;
 +              case 0x3: sprintf(retStr, "SRIX4K"); break;
 +              case 0x4: sprintf(retStr, "SRIX512"); break;
 +              case 0x6: sprintf(retStr, "SRI512"); break;
 +              case 0x7: sprintf(retStr, "SRI4K"); break;
 +              case 0xC: sprintf(retStr, "SRT512"); break;
 +              default: sprintf(retStr, "Unknown"); break;
 +      }
-       return retStr;
- }
- static void print_st_info(uint8_t *data){
-       //uid = first 8 bytes in data
-       PrintAndLog(" UID: %s", sprint_hex(SwapEndian64(data,8,8),8));
-       PrintAndLog(" MFG: %02X, %s", data[6], getTagInfo(data[6]));
-       PrintAndLog("Chip: %02X, %s", data[5]>>2, get_ST_Chip_Model(data[5]>>2));
-       return;
- }
- int HF14BStdReader(uint8_t *data, uint8_t *datalen){
-       //05 00 00 = find one tag in field
-       //1d xx xx xx xx 20 00 08 01 00 = attrib xx=crc
-       //a3 = ?  (resp 03 e2 c2)
-       //02 = ?  (resp 02 6a d3)
-       // 022b (resp 02 67 00 [29  5b])
-       // 0200a40400 (resp 02 67 00 [29 5b])
-       // 0200a4040c07a0000002480300 (resp 02 67 00 [29 5b])
-       // 0200a4040c07a0000002480200 (resp 02 67 00 [29 5b])
-       // 0200a4040006a0000000010100 (resp 02 6a 82 [4b 4c])
-       // 0200a4040c09d27600002545500200 (resp 02 67 00 [29 5b])
-       // 0200a404000cd2760001354b414e4d30310000 (resp 02 6a 82 [4b 4c])
-       // 0200a404000ca000000063504b43532d313500 (resp 02 6a 82 [4b 4c])
-       // 0200a4040010a000000018300301000000000000000000 (resp 02 6a 82 [4b 4c])
-       //03 = ?  (resp 03 [e3 c2])
-       //c2 = ?  (resp c2 [66 15])
-       //b2 = ?  (resp a3 [e9 67])
-       bool crc = true;
-       *datalen = 3;
-       //std read cmd
-       data[0] = 0x05;
-       data[1] = 0x00;
-       data[2] = 0x00;
-       if (HF14BCmdRaw(true, &crc, false, data, datalen, false)==0) return 0;
-       if (data[0] != 0x50  || *datalen != 14 || !crc) return 0;
-       PrintAndLog ("\n14443-3b tag found:");
-       print_atqb_resp(data);
-       return 1;
+     
+     c.arg[0] = datalen;
+     c.arg[1] = reply;
+     c.arg[2] = power;
+     memcpy(c.d.asBytes,data,datalen);
+     
+     SendCommand(&c);
+     
+     if (reply) {
+         if (WaitForResponseTimeout(CMD_ACK,&resp,1000)) {
+             recv = resp.d.asBytes;
+             PrintAndLog("received %i octets",resp.arg[0]);
+             if(resp.arg[0] == 0)
+                 return 0;
+             hexout = (char *)malloc(resp.arg[0] * 3 + 1);
+             if (hexout != NULL) {
+                 uint8_t first, second;
+                 for (int i = 0; i < resp.arg[0]; i++) { // data in hex
+                     sprintf(&hexout[i * 3], "%02X ", recv[i]);
 -                }
 +      }
- int HF14B_ST_Reader(uint8_t *data, uint8_t *datalen){
-       bool crc = true;
-       *datalen = 2;
-       //wake cmd
-       data[0] = 0x06;
-       data[1] = 0x00;
-       //leave power on
-       // verbose on for now for testing - turn off when functional
-       if (HF14BCmdRaw(true, &crc, true, data, datalen, false)==0) return rawClose();
-       if (*datalen != 3 || !crc) return rawClose();
-       uint8_t chipID = data[0];
-       // select
-       data[0] = 0x0E;
-       data[1] = chipID;
-       *datalen = 2;
-       //leave power on
-       // verbose on for now for testing - turn off when functional
-       if (HF14BCmdRaw(true, &crc, true, data, datalen, false)==0) return rawClose();
-       if (*datalen != 3 || !crc || data[0] != chipID) return rawClose();
-       // get uid
-       data[0] = 0x0B;
-       *datalen = 1;
-       //power off
-       // verbose on for now for testing - turn off when functional
-       if (HF14BCmdRaw(true, &crc, true, data, datalen, false)==0) return 0;
-       rawClose();
-       if (*datalen != 10 || !crc) return 0;
-       PrintAndLog("\n14443-3b ST tag found:");
-       print_st_info(data);
-       return 1;
- }
- // test for other 14b type tags (mimic another reader - don't have tags to identify)
- int HF14B_Other_Reader(uint8_t *data, uint8_t *datalen){
-       bool crc = true;
-       *datalen = 4;
-       //std read cmd
-       data[0] = 0x00;
-       data[1] = 0x0b;
-       data[2] = 0x3f;
-       data[3] = 0x80;
-       if (HF14BCmdRaw(true, &crc, false, data, datalen, false)!=0) {
-               if (*datalen > 2 || !crc) {
-                       PrintAndLog ("\n14443-3b tag found:");
-                       PrintAndLog ("Unknown tag type answered to a 0x000b3f80 command ans:");
-                       PrintAndLog ("%s",sprint_hex(data,*datalen));
-                       return 1;
-               }
+                 PrintAndLog("%s", hexout);
+                 free(hexout);
+                               if (resp.arg[0] > 2) {
+                                       ComputeCrc14443(CRC_14443_B, recv, resp.arg[0]-2, &first, &second);
+                                       if(recv[resp.arg[0]-2]==first && recv[resp.arg[0]-1]==second) {
+                                               PrintAndLog("CRC OK");
+                                       } else {
+                                               PrintAndLog("CRC failed");
+                                       }
+                 }
+             } else {
+                 PrintAndLog("malloc failed your client has low memory?");
 -            }
 -        } else {
 -            PrintAndLog("timeout while waiting for reply.");
 -        }
 -    } // if reply
 -    return 0;
 +      }
 +
 +      crc = false;
 +      *datalen = 1;
 +      data[0] = 0x0a;
 +
 +      if (HF14BCmdRaw(true, &crc, false, data, datalen, false)!=0) {
 +              if (*datalen > 0) {
 +                      PrintAndLog ("\n14443-3b tag found:");
 +                      PrintAndLog ("Unknown tag type answered to a 0x0A command ans:");
 +                      PrintAndLog ("%s",sprint_hex(data,*datalen));
 +                      return 1;
 +              }
 +      }
 +      
 +      crc = false;
 +      *datalen = 1;
 +      data[0] = 0x0c;
 +
 +      if (HF14BCmdRaw(true, &crc, false, data, datalen, false)!=0) {
 +              if (*datalen > 0) {
 +                      PrintAndLog ("\n14443-3b tag found:");
 +                      PrintAndLog ("Unknown tag type answered to a 0x0C command ans:");
 +                      PrintAndLog ("%s",sprint_hex(data,*datalen));
 +                      return 1;
 +              }
 +      }
 +
 +      return 0;
 +
  }
  
 -int CmdHF14BWrite( const char *Cmd){
 +int HF14BReader(bool verbose){
 +      uint8_t data[100];
 +      uint8_t datalen = 5;
 +
 +      // try std 14b (atqb)
 +      if (HF14BStdReader(data, &datalen)) return 1;
 +
 +      // try st 14b
 +      if (HF14B_ST_Reader(data, &datalen)) return 1;
 +
 +      // try unknown 14b read commands (to be identified later)
 +      //   could be read of calypso, CEPAS, moneo, or pico pass.
 +      if (HF14B_Other_Reader(data, &datalen)) return 1;
 +
 +      if (verbose) PrintAndLog("no 14443B tag found");
 +      return 0;
 +}
 +
 +int CmdHF14BReader(const char *Cmd){
 +      return HF14BReader(true);
 +}
  
 +int CmdHF14BWrite( const char *Cmd){
  /*
   * For SRIX4K  blocks 00 - 7F
   * hf 14b raw -c -p 09 $srix4kwblock $srix4kwdata
  
  static command_t CommandTable[] = 
  {
 -  {"help",        CmdHelp,        1, "This help"},
 -  {"list",        CmdHF14BList,   0, "[Deprecated] List ISO 14443b history"},
 +      {"help",        CmdHelp,        1, "This help"},
 +      {"list",        CmdHF14BList,   0, "[Deprecated] List ISO 14443b history"},
-       {"reader",      CmdHF14BReader, 0, "Find 14b tag (HF ISO 14443b)"},
-       {"sim",         CmdHF14BSim,     0, "Fake ISO 14443B tag"},
-       {"snoop",       CmdHF14BSnoop,  0, "Eavesdrop ISO 14443B"},
+   {"sim",         CmdHF14BSim,    0, "Fake ISO 14443B tag"},
+   {"snoop",       CmdHF14BSnoop,  0, "Eavesdrop ISO 14443B"},
 -  {"sri512read",  CmdSri512Read,  0, "Read contents of a SRI512 tag"},
 -  {"srix4kread",  CmdSrix4kRead,  0, "Read contents of a SRIX4K tag"},
 -  {"raw",         CmdHF14BCmdRaw, 0, "Send raw hex data to tag"},
 -  {"write",       CmdHF14BWrite,  0, "Write data to a SRI512 | SRIX4K tag"},
 -  {NULL, NULL, 0, NULL}
 +      {"sri512read",  CmdSri512Read,  0, "Read contents of a SRI512 tag"},
 +      {"srix4kread",  CmdSrix4kRead,  0, "Read contents of a SRIX4K tag"},
 +      {"raw",         CmdHF14BCmdRaw, 0, "Send raw hex data to tag"},
 +      {"write",       CmdHF14BWrite,  0, "Write data to a SRI512 | SRIX4K tag"},
 +      {NULL, NULL, 0, NULL}
  };
  
  int CmdHF14B(const char *Cmd)
  {
 -  CmdsParse(CommandTable, Cmd);
 -  return 0;
 +      CmdsParse(CommandTable, Cmd);
 +      return 0;
  }
  
  int CmdHelp(const char *Cmd)
  {
 -  CmdsHelp(CommandTable);
 -  return 0;
 +      CmdsHelp(CommandTable);
 +      return 0;
  }
diff --combined client/cmdhfmfu.c
index cf21a9bf9c1f1acc40fe1fee6113c7e3eccf4b85,25a073d34440b2de98b3c56d67597dbc2df14111..3b577061b9cacf49ecf60815bd083754c96a23fd
  #include "protocols.h"
  #include "data.h"
  
 -#define MAX_UL_BLOCKS      0x0f
 -#define MAX_ULC_BLOCKS     0x2b
 -#define MAX_ULEV1a_BLOCKS  0x13
 -#define MAX_ULEV1b_BLOCKS  0x28
 -#define MAX_NTAG_203       0x29
 -#define MAX_NTAG_210       0x13
 -#define MAX_NTAG_212       0x28
 -#define MAX_NTAG_213       0x2c
 -#define MAX_NTAG_215       0x86
 -#define MAX_NTAG_216       0xe6
 +#define MAX_UL_BLOCKS     0x0f
 +#define MAX_ULC_BLOCKS    0x2b
 +#define MAX_ULEV1a_BLOCKS 0x13
 +#define MAX_ULEV1b_BLOCKS 0x28
 +#define MAX_NTAG_203      0x29
 +#define MAX_NTAG_210      0x13
 +#define MAX_NTAG_212      0x28
 +#define MAX_NTAG_213      0x2c
 +#define MAX_NTAG_215      0x86
 +#define MAX_NTAG_216      0xe6
  #define MAX_MY_D_NFC       0xff
  #define MAX_MY_D_MOVE      0x25
  #define MAX_MY_D_MOVE_LEAN 0x0f
@@@ -129,7 -129,24 +129,7 @@@ static int ul_send_cmd_raw( uint8_t *cm
        memcpy(response, resp.d.asBytes, resplen);
        return resplen;
  }
 -/*
 -static int ul_send_cmd_raw_crc( uint8_t *cmd, uint8_t cmdlen, uint8_t *response, uint16_t responseLength, bool append_crc ) {
 -      UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_RAW | ISO14A_NO_DISCONNECT , cmdlen, 0}};
 -      if (append_crc)
 -              c.arg[0] |= ISO14A_APPEND_CRC;
 -
 -      memcpy(c.d.asBytes, cmd, cmdlen);       
 -      clearCommandBuffer();
 -      SendCommand(&c);
 -      UsbCommand resp;
 -      if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) return -1;
 -      if (!resp.arg[0] && responseLength) return -1;
  
 -      uint16_t resplen = (resp.arg[0] < responseLength) ? resp.arg[0] : responseLength;
 -      memcpy(response, resp.d.asBytes, resplen);
 -      return resplen;
 -}
 -*/
  static int ul_select( iso14a_card_select_t *card ){
  
        ul_switch_on_field();
@@@ -272,7 -289,7 +272,7 @@@ static int ulev1_readSignature( uint8_
  //  send 300000 + crc (read with extra byte(s))
  //  UL responds with read of page 0, fudan doesn't respond.
  //
- //make sure field is off before calling this function
+ // make sure field is off before calling this function
  static int ul_fudan_check( void ){
        iso14a_card_select_t card;
        if ( !ul_select(&card) ) 
@@@ -350,9 -367,7 +350,9 @@@ static int ndef_print_CC(uint8_t *data
        PrintAndLog("  %02X : NDEF Magic Number", data[0]); 
        PrintAndLog("  %02X : version %d.%d supported by tag", data[1], (data[1] & 0xF0) >> 4, data[1] & 0x0f);
        PrintAndLog("  %02X : Physical Memory Size: %d bytes", data[2], (data[2] + 1) * 8);
 -      if ( data[2] == 0x12 )
 +      if ( data[2] == 0x96 )
 +              PrintAndLog("  %02X : NDEF Memory Size: %d bytes", data[2], 48);
 +      else if ( data[2] == 0x12 )
                PrintAndLog("  %02X : NDEF Memory Size: %d bytes", data[2], 144);
        else if ( data[2] == 0x3e )
                PrintAndLog("  %02X : NDEF Memory Size: %d bytes", data[2], 496);
@@@ -880,7 -895,7 +880,7 @@@ int CmdHF14AMfUInfo(const char *Cmd)
  //
  int CmdHF14AMfUWrBl(const char *Cmd){
  
 -      int blockNo = -1;
 +      int blockNo = -1;       
        bool errors = false;
        bool hasAuthKey = false;
        bool hasPwdKey = false;
        uint8_t data[16] = {0x00};
        uint8_t authenticationkey[16] = {0x00};
        uint8_t *authKeyPtr = authenticationkey;
-       
        while(param_getchar(Cmd, cmdp) != 0x00)
        {
                switch(param_getchar(Cmd, cmdp))
                                blockNo = param_get8(Cmd, cmdp+1);
                                if (blockNo < 0) {
                                        PrintAndLog("Wrong block number");
 -                                      errors = true;
 +                                      errors = true;                                                                  
                                }
                                cmdp += 2;
                                break;
                PrintAndLog("block number too large. Max block is %u/0x%02X \n", maxblockno,maxblockno);
                return usage_hf_mfu_wrbl();
        }
-       
        // Swap endianness 
        if (swapEndian && hasAuthKey) authKeyPtr = SwapEndian64(authenticationkey, 16, 8);
        if (swapEndian && hasPwdKey)  authKeyPtr = SwapEndian64(authenticationkey, 4, 4);
  
 -      if ( blockNo <= 3)
 +      if ( blockNo <= 3)              
                PrintAndLog("Special Block: %0d (0x%02X) [ %s]", blockNo, blockNo, sprint_hex(blockdata, 4));
        else
                PrintAndLog("Block: %0d (0x%02X) [ %s]", blockNo, blockNo, sprint_hex(blockdata, 4));
 -
 +      
        //Send write Block
        UsbCommand c = {CMD_MIFAREU_WRITEBL, {blockNo}};
        memcpy(c.d.asBytes,blockdata,4);
  
 -      if ( hasAuthKey ) {
 +      if ( hasAuthKey ){
                c.arg[1] = 1;
                memcpy(c.d.asBytes+4,authKeyPtr,16);
        }
                c.arg[1] = 2;
                memcpy(c.d.asBytes+4,authKeyPtr,4);
        }
 -
 +      
        clearCommandBuffer();
        SendCommand(&c);
        UsbCommand resp;
        } else {
                PrintAndLog("Command execute timeout");
        }
 -
 +      
        return 0;
  }
  //
@@@ -1051,15 -1066,15 +1051,15 @@@ int CmdHF14AMfURdBl(const char *Cmd)
                                blockNo = param_get8(Cmd, cmdp+1);
                                if (blockNo < 0) {
                                        PrintAndLog("Wrong block number");
 -                                      errors = true;
 +                                      errors = true;                                                                  
                                }
                                cmdp += 2;
                                break;
                        case 'l':
                        case 'L':
                                swapEndian = true;
 -                              cmdp++;
 -                              break;
 +                              cmdp++; 
 +                              break;                          
                        default:
                                PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
                                errors = true;
                PrintAndLog("block number to large. Max block is %u/0x%02X \n", maxblockno,maxblockno);
                return usage_hf_mfu_rdbl();
        }
-       
        // Swap endianness 
        if (swapEndian && hasAuthKey) authKeyPtr = SwapEndian64(authenticationkey, 16, 8);
        if (swapEndian && hasPwdKey)  authKeyPtr = SwapEndian64(authenticationkey, 4, 4);
 -
 +      
        //Read Block
        UsbCommand c = {CMD_MIFAREU_READBL, {blockNo}};
        if ( hasAuthKey ){
                c.arg[1] = 2;
                memcpy(c.d.asBytes,authKeyPtr,4);
        }
 -
 +      
        clearCommandBuffer();
        SendCommand(&c);
        UsbCommand resp;
@@@ -1175,7 -1190,7 +1175,7 @@@ int usage_hf_mfu_rdbl(void) 
  int usage_hf_mfu_wrbl(void) {
        PrintAndLog("Write a block. It autodetects card type.\n");              
        PrintAndLog("Usage:  hf mfu wrbl b <block number> d <data> k <key> l\n");
 -      PrintAndLog("  Options:");
 +      PrintAndLog("  Options:");      
        PrintAndLog("  b <no>   : block to write");
        PrintAndLog("  d <data> : block data - (8 hex symbols)");
        PrintAndLog("  k <key>  : (optional) key for authentication [UL-C 16bytes, EV1/NTAG 4bytes]");
        return 0;
  }
  
 +int usage_hf_mfu_eload(void) {
 +      PrintAndLog("It loads emulator dump from the file `filename.eml`\n");
 +      PrintAndLog("Usage:  hf mf eload t <card memory> i <file name w/o `.eml`>\n");
 +      PrintAndLog("  Options:");      
 +      PrintAndLog("  t <card memory> : Tag memorysize/type");
 +      PrintAndLog("  i <file>        : file name w/o `.eml`");
 +      PrintAndLog("");
 +      PrintAndLog("    sample : hf mfu eload filename");
 +      PrintAndLog("           : hf mfu eload 4 filename");
 +      return 0;
 +}
 +
  //
  //  Mifare Ultralight / Ultralight-C / Ultralight-EV1
  //  Read and Dump Card Contents,  using auto detection of tag size.
@@@ -1374,11 -1377,11 +1374,11 @@@ int CmdHF14AMfUDump(const char *Cmd)
                }
                switch(i){
                        case 3: tmplockbit = bit[4]; break;
 -                      case 4: tmplockbit = bit[3]; break;
 -                      case 5: tmplockbit = bit[2]; break;
 -                      case 6: tmplockbit = bit[1]; break;
 -                      case 7: tmplockbit = bit[0]; break;
 -                      case 8: tmplockbit = bit[15]; break;
 +                      case 4: tmplockbit = bit[3]; break;
 +                      case 5: tmplockbit = bit[2]; break;
 +                      case 6: tmplockbit = bit[1]; break;
 +                      case 7: tmplockbit = bit[0]; break;
 +                      case 8: tmplockbit = bit[15]; break;
                        case 9: tmplockbit = bit[14]; break;
                        case 10: tmplockbit = bit[13]; break;
                        case 11: tmplockbit = bit[12]; break;
@@@ -1589,10 -1592,10 +1589,10 @@@ int CmdTestDES(const char * cmd
  //
  int CmdHF14AMfucSetPwd(const char *Cmd){
  
 -      uint8_t pwd[16] = {0x00};
 +      uint8_t pwd[16] = {0x00};       
        
        char cmdp = param_getchar(Cmd, 0);
 -      
 +
        if (strlen(Cmd) == 0  || cmdp == 'h' || cmdp == 'H') {  
                PrintAndLog("Usage:  hf mfu setpwd <password (32 hex symbols)>");
                PrintAndLog("       [password] - (32 hex symbols)");
@@@ -1664,7 -1667,7 +1664,7 @@@ int CmdHF14AMfucSetUid(const char *Cmd)
                PrintAndLog("Command execute timeout");
                return 2;
        }
 -      
 +
        // save old block2.
        uint8_t oldblock2[4] = {0x00};
        memcpy(resp.d.asBytes, oldblock2, 4);
                PrintAndLog("Command execute timeout");
                return 3;
        }
 -      
 +
        // block 1.
        c.arg[0] = 1;
        c.d.asBytes[0] = uid[3];
  }
  
  int CmdHF14AMfuGenDiverseKeys(const char *Cmd){
 -
 +      
        uint8_t iv[8] = { 0x00 };
        uint8_t block = 0x07;
 -
 +      
        // UL-EV1
        //04 57 b6 e2 05 3f 80 UID
        //4a f8 4b 19   PWD
        
        uint8_t mix[8] = { 0x00 };
        uint8_t divkey[8] = { 0x00 };
 -
 +      
        memcpy(mix, mifarekeyA, 4);
 -
 +      
        mix[4] = mifarekeyA[4] ^ uid[0];
        mix[5] = mifarekeyA[5] ^ uid[1];
        mix[6] = block ^ uid[2];
        mix[7] = uid[3];
 -
 +      
        des3_context ctx = { 0x00 };
        des3_set2key_enc(&ctx, masterkey);
  
        PrintAndLog("Mifare key   :\t %s", sprint_hex(mifarekeyA, sizeof(mifarekeyA)));
        PrintAndLog("Message      :\t %s", sprint_hex(mix, sizeof(mix)));
        PrintAndLog("Diversified key: %s", sprint_hex(divkey+1, 6));
 -
 +              
        PrintAndLog("\n DES version");
 -
 +      
        for (int i=0; i < sizeof(mifarekeyA); ++i){
                dkeyA[i] = (mifarekeyA[i] << 1) & 0xff;
                dkeyA[6] |=  ((mifarekeyA[i] >> 7) & 1) << (i+1);
        memcpy(dmkey+8, dkeyB, 8);
        memcpy(dmkey+16, dkeyA, 8);
        memset(iv, 0x00, 8);
 -
 +      
        des3_set3key_enc(&ctx, dmkey);
  
        des3_crypt_cbc(&ctx  // des3_context
        // return;
  // }
  
 +int CmdHF14AMfuELoad(const char *Cmd)
 +{
 +      FILE * f;
 +      char filename[FILE_PATH_SIZE];
 +      char *fnameptr = filename;
 +      char buf[64] = {0x00};
 +      uint8_t buf8[64] = {0x00};
 +      int i, len, blockNum, numBlocks;
 +      int nameParamNo = 1;
 +      
 +      char ctmp = param_getchar(Cmd, 0);
 +              
 +      if ( ctmp == 'h' || ctmp == 0x00) {
 +              return usage_hf_mfu_eload();
 +      }       
 +/*
 +      switch (ctmp) {
 +              case '0' : numBlocks = 5*4; break;
 +              case '1' : 
 +              case '\0': numBlocks = 16*4; break;
 +              case '2' : numBlocks = 32*4; break;
 +              case '4' : numBlocks = 256; break;
 +              default:  {
 +                      numBlocks = 16*4;
 +                      nameParamNo = 0;
 +              }
 +      }
 +
 +      len = param_getstr(Cmd,nameParamNo,filename);
 +      
 +      if (len > FILE_PATH_SIZE - 4) len = FILE_PATH_SIZE - 4;
 +
 +      fnameptr += len;
 +
 +      sprintf(fnameptr, ".eml"); 
 +      
 +      // open file
 +      f = fopen(filename, "r");
 +      if (f == NULL) {
 +              PrintAndLog("File %s not found or locked", filename);
 +              return 1;
 +      }
 +      
 +      blockNum = 0;
 +      while(!feof(f)){
 +              memset(buf, 0, sizeof(buf));
 +              
 +              if (fgets(buf, sizeof(buf), f) == NULL) {
 +                      
 +                      if (blockNum >= numBlocks) break;
 +                      
 +                      PrintAndLog("File reading error.");
 +                      fclose(f);
 +                      return 2;
 +              }
 +              
 +              if (strlen(buf) < 32){
 +                      if(strlen(buf) && feof(f))
 +                              break;
 +                      PrintAndLog("File content error. Block data must include 32 HEX symbols");
 +                      fclose(f);
 +                      return 2;
 +              }
 +              
 +              for (i = 0; i < 32; i += 2) {
 +                      sscanf(&buf[i], "%02x", (unsigned int *)&buf8[i / 2]);
 +              }
 +              
 +              if (mfEmlSetMem(buf8, blockNum, 1)) {
 +                      PrintAndLog("Cant set emul block: %3d", blockNum);
 +                      fclose(f);
 +                      return 3;
 +              }
 +              printf(".");
 +              blockNum++;
 +              
 +              if (blockNum >= numBlocks) break;
 +      }
 +      fclose(f);
 +      printf("\n");
 +      
 +      if ((blockNum != numBlocks)) {
 +              PrintAndLog("File content error. Got %d must be %d blocks.",blockNum, numBlocks);
 +              return 4;
 +      }
 +      PrintAndLog("Loaded %d blocks from file: %s", blockNum, filename);
 +      */
 +      return 0;
 +}
 +
 +
  //------------------------------------
  // Menu Stuff
  //------------------------------------
@@@ -1913,7 -1825,6 +1913,7 @@@ static command_t CommandTable[] 
        {"dump",        CmdHF14AMfUDump,        0, "Dump Ultralight / Ultralight-C / NTAG tag to binary file"},
        {"rdbl",        CmdHF14AMfURdBl,        0, "Read block"},
        {"wrbl",        CmdHF14AMfUWrBl,        0, "Write block"},
 +      {"eload",       CmdHF14AMfuELoad,       0, "Load from file emulator dump"},
        {"cauth",       CmdHF14AMfucAuth,       0, "Authentication    - Ultralight C"},
        {"setpwd",      CmdHF14AMfucSetPwd, 1, "Set 3des password - Ultralight-C"},
        {"setuid",      CmdHF14AMfucSetUid, 1, "Set UID - MAGIC tags only"},
index 1881b561e57596cfd74ab03312d2956dd70be241,b3a7f4ec94c3e3663fc3db40fb9de301dbb1d065..19aa28c23992e20fcc0c9d1ca62e74e407320660
@@@ -89,7 -89,6 +89,6 @@@ typedef struct 
  
  // For the 13.56 MHz tags
  #define CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693                             0x0300
- #define CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443                             0x0301
  #define CMD_READ_SRI512_TAG                                               0x0303
  #define CMD_READ_SRIX4K_TAG                                               0x0304
  #define CMD_READER_ISO_15693                                              0x0310
  #define CMD_SIMULATE_HITAG                                                0x0371
  #define CMD_READER_HITAG                                                  0x0372
  
- #define CMD_SIMULATE_TAG_HF_LISTEN                                        0x0380
- #define CMD_SIMULATE_TAG_ISO_14443                                        0x0381
- #define CMD_SNOOP_ISO_14443                                               0x0382
+ #define CMD_SIMULATE_TAG_ISO_14443B                                       0x0381
+ #define CMD_SNOOP_ISO_14443B                                              0x0382
  #define CMD_SNOOP_ISO_14443a                                              0x0383
  #define CMD_SIMULATE_TAG_ISO_14443a                                       0x0384
  #define CMD_READER_ISO_14443a                                             0x0385
  #define CMD_READER_LEGIC_RF                                               0x0388
  #define CMD_WRITER_LEGIC_RF                                               0x0389
  #define CMD_EPA_PACE_COLLECT_NONCE                                        0x038A
 +#define CMD_EPA_PACE_REPLAY                                               0x038B
  
  #define CMD_SNOOP_ICLASS                                                  0x0392
  #define CMD_SIMULATE_TAG_ICLASS                                           0x0393
Impressum, Datenschutz