]> git.zerfleddert.de Git - proxmark3-svn/commitdiff
Merge branch 'master' into topaz
authorpwpiwi <pwpiwi@users.noreply.github.com>
Tue, 25 Aug 2015 05:53:00 +0000 (07:53 +0200)
committerpwpiwi <pwpiwi@users.noreply.github.com>
Tue, 25 Aug 2015 05:53:00 +0000 (07:53 +0200)
1  2 
armsrc/BigBuf.c
armsrc/iso14443a.c
client/Makefile
client/cmdhf.c

diff --combined armsrc/BigBuf.c
index a22c0cb0e499692054b66413c1af5214b290f063,a938d5c68db9a193463700f315564ca45dfd3267..6b52a5894545beaa352273aeea608945a6ada7b0
@@@ -88,6 -88,16 +88,16 @@@ void BigBuf_free_keep_EM(void
        }
  }
  
+ void BigBuf_print_status(void)
+ {
+       Dbprintf("Memory");
+       Dbprintf("  BIGBUF_SIZE.............%d", BIGBUF_SIZE);
+       Dbprintf("  BigBuf_hi  .............%d", BigBuf_hi);
+       Dbprintf("Tracing");
+       Dbprintf("  tracing ................%d", tracing);
+       Dbprintf("  traceLen ...............%d", traceLen);
+ }
  
  // return the maximum trace length (i.e. the unallocated size of BigBuf)
  uint16_t BigBuf_max_traceLen(void)
@@@ -168,12 -178,8 +178,12 @@@ bool RAMFUNC LogTrace(const uint8_t *bt
        traceLen += iLen;
  
        // parity bytes
 -      if (parity != NULL && iLen != 0) {
 -              memcpy(trace + traceLen, parity, num_paritybytes);
 +      if (iLen != 0) {
 +              if (parity != NULL) {
 +                      memcpy(trace + traceLen, parity, num_paritybytes);
 +              } else {
 +                      memset(trace + traceLen, 0x00, num_paritybytes);
 +              }
        }
        traceLen += num_paritybytes;
  
@@@ -222,8 -228,6 +232,8 @@@ int LogTraceHitag(const uint8_t * btByt
  
        return TRUE;
  }
 +
 +
  // Emulator memory
  uint8_t emlSet(uint8_t *data, uint32_t offset, uint32_t length){
        uint8_t* mem = BigBuf_get_EM_addr();
diff --combined armsrc/iso14443a.c
index a4e5ceaf1ece9ea5bc57eeade9c2ed77aa1ccc5e,f81a1a99a6a44dff93c6ed1e52f39a3d72bbde34..9fa9fe4ff61d8724036feeebeaa182a98b84a341
@@@ -213,12 -213,6 +213,12 @@@ void AppendCrc14443a(uint8_t* data, in
        ComputeCrc14443(CRC_14443_A,data,len,data+len,data+len+1);
  }
  
 +void AppendCrc14443b(uint8_t* data, int len)
 +{
 +      ComputeCrc14443(CRC_14443_B,data,len,data+len,data+len+1);
 +}
 +
 +
  //=============================================================================
  // ISO 14443 Type A - Miller decoder
  //=============================================================================
  static tUart Uart;
  
  // Lookup-Table to decide if 4 raw bits are a modulation.
 -// We accept two or three consecutive "0" in any position with the rest "1"
 +// We accept the following:
 +// 0001  -   a 3 tick wide pause
 +// 0011  -   a 2 tick wide pause, or a three tick wide pause shifted left
 +// 0111  -   a 2 tick wide pause shifted left
 +// 1001  -   a 2 tick wide pause shifted right
  const bool Mod_Miller_LUT[] = {
 -      TRUE,  TRUE,  FALSE, TRUE,  FALSE, FALSE, FALSE, FALSE,
 -      TRUE,  TRUE,  FALSE, FALSE, TRUE,  FALSE, FALSE, FALSE
 +      FALSE,  TRUE, FALSE, TRUE,  FALSE, FALSE, FALSE, TRUE,
 +      FALSE,  TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE
  };
 -#define IsMillerModulationNibble1(b) (Mod_Miller_LUT[(b & 0x00F0) >> 4])
 -#define IsMillerModulationNibble2(b) (Mod_Miller_LUT[(b & 0x000F)])
 +#define IsMillerModulationNibble1(b) (Mod_Miller_LUT[(b & 0x000000F0) >> 4])
 +#define IsMillerModulationNibble2(b) (Mod_Miller_LUT[(b & 0x0000000F)])
  
  void UartReset()
  {
        Uart.parityLen = 0;                                     // number of decoded parity bytes
        Uart.shiftReg = 0;                                      // shiftreg to hold decoded data bits
        Uart.parityBits = 0;                            // holds 8 parity bits
 -      Uart.twoBits = 0x0000;                          // buffer for 2 Bits
 -      Uart.highCnt = 0;
        Uart.startTime = 0;
        Uart.endTime = 0;
  }
@@@ -266,7 -258,6 +266,7 @@@ void UartInit(uint8_t *data, uint8_t *p
  {
        Uart.output = data;
        Uart.parity = parity;
 +      Uart.fourBits = 0x00000000;                     // clear the buffer for 4 Bits
        UartReset();
  }
  
  static RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time)
  {
  
 -      Uart.twoBits = (Uart.twoBits << 8) | bit;
 +      Uart.fourBits = (Uart.fourBits << 8) | bit;
        
        if (Uart.state == STATE_UNSYNCD) {                                                                                      // not yet synced
        
 -              if (Uart.highCnt < 2) {                                                                                                 // wait for a stable unmodulated signal
 -                      if (Uart.twoBits == 0xffff) {
 -                              Uart.highCnt++;
 -                      } else {
 -                              Uart.highCnt = 0;
 -                      }
 -              } else {        
 -                      Uart.syncBit = 0xFFFF;                                                                                          // not set
 -                                                                                                                                                              // we look for a ...1111111100x11111xxxxxx pattern (the start bit)
 -                      if              ((Uart.twoBits & 0xDF00) == 0x1F00) Uart.syncBit = 8;           // mask is   11x11111 xxxxxxxx, 
 -                                                                                                                                                              // check for 00x11111 xxxxxxxx
 -                      else if ((Uart.twoBits & 0xEF80) == 0x8F80) Uart.syncBit = 7;           // both masks shifted right one bit, left padded with '1'
 -                      else if ((Uart.twoBits & 0xF7C0) == 0xC7C0) Uart.syncBit = 6;           // ...
 -                      else if ((Uart.twoBits & 0xFBE0) == 0xE3E0) Uart.syncBit = 5;
 -                      else if ((Uart.twoBits & 0xFDF0) == 0xF1F0) Uart.syncBit = 4;
 -                      else if ((Uart.twoBits & 0xFEF8) == 0xF8F8) Uart.syncBit = 3;
 -                      else if ((Uart.twoBits & 0xFF7C) == 0xFC7C) Uart.syncBit = 2;
 -                      else if ((Uart.twoBits & 0xFFBE) == 0xFE3E) Uart.syncBit = 1;
 -                      if (Uart.syncBit != 0xFFFF) {                                                                           // found a sync bit
 -                              Uart.startTime = non_real_time?non_real_time:(GetCountSspClk() & 0xfffffff8);
 -                              Uart.startTime -= Uart.syncBit;
 -                              Uart.endTime = Uart.startTime;
 -                              Uart.state = STATE_START_OF_COMMUNICATION;
 -                      }
 +              Uart.syncBit = 9999;                                                                                                    // not set
 +              // The start bit is one ore more Sequence Y followed by a Sequence Z (... 11111111 00x11111). We need to distinguish from
 +              // Sequence X followed by Sequence Y followed by Sequence Z (111100x1 11111111 00x11111)
 +              // we therefore look for a ...xx11111111111100x11111xxxxxx... pattern 
 +              // (12 '1's followed by 2 '0's, eventually followed by another '0', followed by 5 '1's)
 +              #define ISO14443A_STARTBIT_MASK         0x07FFEF80                                                      // mask is    00000111 11111111 11101111 10000000
 +              #define ISO14443A_STARTBIT_PATTERN      0x07FF8F80                                                      // pattern is 00000111 11111111 10001111 10000000
 +              if              ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 0)) == ISO14443A_STARTBIT_PATTERN >> 0) Uart.syncBit = 7;
 +              else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 1)) == ISO14443A_STARTBIT_PATTERN >> 1) Uart.syncBit = 6;
 +              else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 2)) == ISO14443A_STARTBIT_PATTERN >> 2) Uart.syncBit = 5;
 +              else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 3)) == ISO14443A_STARTBIT_PATTERN >> 3) Uart.syncBit = 4;
 +              else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 4)) == ISO14443A_STARTBIT_PATTERN >> 4) Uart.syncBit = 3;
 +              else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 5)) == ISO14443A_STARTBIT_PATTERN >> 5) Uart.syncBit = 2;
 +              else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 6)) == ISO14443A_STARTBIT_PATTERN >> 6) Uart.syncBit = 1;
 +              else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 7)) == ISO14443A_STARTBIT_PATTERN >> 7) Uart.syncBit = 0;
 +
 +              if (Uart.syncBit != 9999) {                                                                                             // found a sync bit
 +                      Uart.startTime = non_real_time?non_real_time:(GetCountSspClk() & 0xfffffff8);
 +                      Uart.startTime -= Uart.syncBit;
 +                      Uart.endTime = Uart.startTime;
 +                      Uart.state = STATE_START_OF_COMMUNICATION;
                }
  
        } else {
  
 -              if (IsMillerModulationNibble1(Uart.twoBits >> Uart.syncBit)) {                  
 -                      if (IsMillerModulationNibble2(Uart.twoBits >> Uart.syncBit)) {          // Modulation in both halves - error
 +              if (IsMillerModulationNibble1(Uart.fourBits >> Uart.syncBit)) {                 
 +                      if (IsMillerModulationNibble2(Uart.fourBits >> Uart.syncBit)) {         // Modulation in both halves - error
                                UartReset();
                        } else {                                                                                                                        // Modulation in first half = Sequence Z = logic "0"
                                if (Uart.state == STATE_MILLER_X) {                                                             // error - must not follow after X
                                }
                        }
                } else {
 -                      if (IsMillerModulationNibble2(Uart.twoBits >> Uart.syncBit)) {          // Modulation second half = Sequence X = logic "1"
 +                      if (IsMillerModulationNibble2(Uart.fourBits >> Uart.syncBit)) {         // Modulation second half = Sequence X = logic "1"
                                Uart.bitCount++;
                                Uart.shiftReg = (Uart.shiftReg >> 1) | 0x100;                                   // add a 1 to the shiftreg
                                Uart.state = STATE_MILLER_X;
                                                return TRUE;                                                                                    // we are finished with decoding the raw data sequence
                                        } else {
                                                UartReset();                                                                                    // Nothing received - start over
 -                                              Uart.highCnt = 1;
                                        }
                                }
                                if (Uart.state == STATE_START_OF_COMMUNICATION) {                               // error - must not follow directly after SOC
                                        UartReset();
 -                                      Uart.highCnt = 1;
                                } else {                                                                                                                // a logic "0"
                                        Uart.bitCount++;
                                        Uart.shiftReg = (Uart.shiftReg >> 1);                                           // add a 0 to the shiftreg
@@@ -684,9 -680,6 +684,9 @@@ void RAMFUNC SnoopIso14443a(uint8_t par
  
                                        // And ready to receive another response.
                                        DemodReset();
 +                                      // And reset the Miller decoder including itS (now outdated) input buffer
 +                                      UartInit(receivedCmd, receivedCmdPar);
 +
                                        LED_C_OFF();
                                } 
                                TagIsActive = (Demod.state != DEMOD_UNSYNCD);
@@@ -1070,7 -1063,6 +1070,6 @@@ void SimulateIso14443aTag(int tagType, 
        LED_A_ON();
        for(;;) {
                // Clean receive command buffer
-               
                if(!GetIso14443aCommandFromReader(receivedCmd, receivedCmdPar, &len)) {
                        DbpString("Button press");
                        break;
@@@ -1344,7 -1336,7 +1343,7 @@@ void CodeIso14443aBitsAsReaderPar(cons
                }
  
                // Only transmit parity bit if we transmitted a complete byte
 -              if (j == 8) {
 +              if (j == 8 && parity != NULL) {
                        // Get the parity bit
                        if (parity[i>>3] & (0x80 >> (i&0x0007))) {
                                // Sequence X
@@@ -1638,7 -1630,6 +1637,7 @@@ static int GetIso14443aAnswerFromTag(ui
        }
  }
  
 +
  void ReaderTransmitBitsPar(uint8_t* frame, uint16_t bits, uint8_t *par, uint32_t *timing)
  {
        CodeIso14443aBitsAsReaderPar(frame, bits, par);
        }
  }
  
 +
  void ReaderTransmitPar(uint8_t* frame, uint16_t len, uint8_t *par, uint32_t *timing)
  {
    ReaderTransmitBitsPar(frame, len*8, par, timing);
  }
  
 +
  void ReaderTransmitBits(uint8_t* frame, uint16_t len, uint32_t *timing)
  {
    // Generate parity and redirect
    ReaderTransmitBitsPar(frame, len, par, timing);
  }
  
 +
  void ReaderTransmit(uint8_t* frame, uint16_t len, uint32_t *timing)
  {
    // Generate parity and redirect
@@@ -1730,11 -1718,6 +1729,11 @@@ int iso14443a_select_card(byte_t *uid_p
                memset(uid_ptr,0,10);
        }
  
 +      // check for proprietary anticollision:
 +      if ((resp[0] & 0x1F) == 0) {
 +              return 3;
 +      }
 +      
        // OK we will select at least at cascade 1, lets see if first byte of UID was 0x88 in
        // which case we need to make a cascade 2 request and select - this is a long UID
        // While the UID is not complete, the 3nd bit (from the right) is set in the SAK.
@@@ -1943,38 -1926,15 +1942,38 @@@ void ReaderIso14443a(UsbCommand *c
  
        if(param & ISO14A_RAW) {
                if(param & ISO14A_APPEND_CRC) {
 -                      AppendCrc14443a(cmd,len);
 +                      if(param & ISO14A_TOPAZMODE) {
 +                              AppendCrc14443b(cmd,len);
 +                      } else {
 +                              AppendCrc14443a(cmd,len);
 +                      }
                        len += 2;
                        if (lenbits) lenbits += 16;
                }
 -              if(lenbits>0) {
 -                      GetParity(cmd, lenbits/8, par);
 -                      ReaderTransmitBitsPar(cmd, lenbits, par, NULL);
 -              } else {
 -                      ReaderTransmit(cmd,len, NULL);
 +              if(lenbits>0) {                         // want to send a specific number of bits (e.g. short commands)
 +                      if(param & ISO14A_TOPAZMODE) {
 +                              int bits_to_send = lenbits;
 +                              uint16_t i = 0;
 +                              ReaderTransmitBitsPar(&cmd[i++], MIN(bits_to_send, 7), NULL, NULL);             // first byte is always short (7bits) and no parity
 +                              bits_to_send -= 7;
 +                              while (bits_to_send > 0) {
 +                                      ReaderTransmitBitsPar(&cmd[i++], MIN(bits_to_send, 8), NULL, NULL);     // following bytes are 8 bit and no parity
 +                                      bits_to_send -= 8;
 +                              }
 +                      } else {
 +                              GetParity(cmd, lenbits/8, par);
 +                              ReaderTransmitBitsPar(cmd, lenbits, par, NULL);                                                 // bytes are 8 bit with odd parity
 +                      }
 +              } else {                                        // want to send complete bytes only
 +                      if(param & ISO14A_TOPAZMODE) {
 +                              uint16_t i = 0;
 +                              ReaderTransmitBitsPar(&cmd[i++], 7, NULL, NULL);                                                // first byte: 7 bits, no paritiy
 +                              while (i < len) {
 +                                      ReaderTransmitBitsPar(&cmd[i++], 8, NULL, NULL);                                        // following bytes: 8 bits, no paritiy
 +                              }
 +                      } else {
 +                              ReaderTransmit(cmd,len, NULL);                                                                                  // 8 bits, odd parity
 +                      }
                }
                arg0 = ReaderReceive(buf, par);
                cmd_send(CMD_ACK,arg0,0,0,buf,sizeof(buf));
@@@ -2854,7 -2814,7 +2853,7 @@@ void RAMFUNC SniffMifare(uint8_t param
                                        if (MfSniffLogic(receivedCmd, Uart.len, Uart.parity, Uart.bitCount, TRUE)) break;
  
                                        /* And ready to receive another command. */
 -                                      UartReset();
 +                                      UartInit(receivedCmd, receivedCmdPar);
                                        
                                        /* And also reset the demod code */
                                        DemodReset();
  
                                        // And ready to receive another response.
                                        DemodReset();
 +                                      // And reset the Miller decoder including its (now outdated) input buffer
 +                                      UartInit(receivedCmd, receivedCmdPar);
                                }
                                TagIsActive = (Demod.state != DEMOD_UNSYNCD);
                        }
diff --combined client/Makefile
index f768f3d8ef1e3e6328472151a8433a5b72fcb437,15b1cbca3cd76660fbdb69b7841dc199334a70f1..903cbf9ef35fa315a3a2f82ee5331d3a636c6cf6
@@@ -57,14 -57,14 +57,14 @@@ CORESRCS =         uart.c 
  
  
  CMDSRCS =     nonce2key/crapto1.c\
 -              nonce2key/crypto1.c\
 -              nonce2key/nonce2key.c\
 -              loclass/cipher.c \
 -              loclass/cipherutils.c \
 -              loclass/des.c \
 -              loclass/ikeys.c \
 -              loclass/elite_crack.c\
 -              loclass/fileutils.c\
 +                      nonce2key/crypto1.c\
 +                      nonce2key/nonce2key.c\
 +                      loclass/cipher.c \
 +                      loclass/cipherutils.c \
 +                      loclass/des.c \
 +                      loclass/ikeys.c \
 +                      loclass/elite_crack.c\
 +                      loclass/fileutils.c\
                        mifarehost.c\
                        crc.c \
                        crc16.c \
                        cmdhficlass.c \
                        cmdhfmf.c \
              cmdhfmfu.c \
 +                      cmdhftopaz.c \
                        cmdhw.c \
                        cmdlf.c \
                        cmdlfio.c \
                        cmdlfhid.c \
+                       cmdlfawid.c \
                        cmdlfem4x.c \
                        cmdlfhitag.c \
                        cmdlfti.c \
diff --combined client/cmdhf.c
index 4777a0f40295b40408e03a3a505eeb73560f041c,f8daff7e5ef106f20721ef1dfd53a706648da8f2..ee0b4fd8c1855f83da631df3476ad46b6de83bbd
@@@ -23,7 -23,6 +23,7 @@@
  #include "cmdhficlass.h"
  #include "cmdhfmf.h"
  #include "cmdhfmfu.h"
 +#include "cmdhftopaz.h"
  #include "protocols.h"
  
  static int CmdHelp(const char *Cmd);
@@@ -188,26 -187,6 +188,26 @@@ void annotateIso15693(char *exp, size_
        }
  }
  
 +
 +void annotateTopaz(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize)
 +{
 +      switch(cmd[0]) {
 +              case TOPAZ_REQA                                         :snprintf(exp, size, "REQA");break;
 +              case TOPAZ_WUPA                                         :snprintf(exp, size, "WUPA");break;
 +              case TOPAZ_RID                                          :snprintf(exp, size, "RID");break;
 +              case TOPAZ_RALL                                         :snprintf(exp, size, "RALL");break;
 +              case TOPAZ_READ                                         :snprintf(exp, size, "READ");break;
 +              case TOPAZ_WRITE_E                                      :snprintf(exp, size, "WRITE-E");break;
 +              case TOPAZ_WRITE_NE                                     :snprintf(exp, size, "WRITE-NE");break;
 +              case TOPAZ_RSEG                                         :snprintf(exp, size, "RSEG");break;
 +              case TOPAZ_READ8                                        :snprintf(exp, size, "READ8");break;
 +              case TOPAZ_WRITE_E8                                     :snprintf(exp, size, "WRITE-E8");break;
 +              case TOPAZ_WRITE_NE8                            :snprintf(exp, size, "WRITE-NE8");break;
 +              default:                            snprintf(exp,size,"?"); break;
 +      }
 +}
 +
 +
  /**
  06 00 = INITIATE
  0E xx = SELECT ID (xx = Chip-ID)
@@@ -239,34 -218,7 +239,34 @@@ void annotateIso14443b(char *exp, size_
  }
  
  /**
 - * @brief iso14443B_CRC_Ok Checks CRC in command or response
 + * @brief iso14443A_CRC_check Checks CRC in command or response
 + * @param isResponse
 + * @param data
 + * @param len
 + * @return  0 : CRC-command, CRC not ok
 + *          1 : CRC-command, CRC ok
 + *          2 : Not crc-command
 + */
 +
 +uint8_t iso14443A_CRC_check(bool isResponse, uint8_t* data, uint8_t len)
 +{
 +      uint8_t b1,b2;
 +
 +      if(len <= 2) return 2;
 +
 +      if(isResponse & (len < 6)) return 2;
 +      
 +      ComputeCrc14443(CRC_14443_A, data, len-2, &b1, &b2);
 +      if (b1 != data[len-2] || b2 != data[len-1]) {
 +              return 0;
 +      } else {
 +              return 1;
 +      }
 +}
 +
 +
 +/**
 + * @brief iso14443B_CRC_check Checks CRC in command or response
   * @param isResponse
   * @param data
   * @param len
@@@ -283,10 -235,9 +283,10 @@@ uint8_t iso14443B_CRC_check(bool isResp
  
        ComputeCrc14443(CRC_14443_B, data, len-2, &b1, &b2);
        if(b1 != data[len-2] || b2 != data[len-1]) {
 -        return 0;
 +              return 0;
 +      } else {
 +              return 1;
        }
 -      return 1;
  }
  
  /**
@@@ -350,66 -301,11 +350,66 @@@ uint8_t iclass_CRC_check(bool isRespons
        }
  }
  
 -uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, uint8_t protocol, bool showWaitCycles)
 +
 +bool is_last_record(uint16_t tracepos, uint8_t *trace, uint16_t traceLen)
  {
 -      bool isResponse;
 -      uint16_t duration, data_len, parity_len;
 +      return(tracepos + sizeof(uint32_t) + sizeof(uint16_t) + sizeof(uint16_t) >= traceLen);
 +}
 +
 +
 +bool next_record_is_response(uint16_t tracepos, uint8_t *trace)
 +{
 +      uint16_t next_records_datalen = *((uint16_t *)(trace + tracepos + sizeof(uint32_t) + sizeof(uint16_t)));
 +      
 +      return(next_records_datalen & 0x8000);
 +}
 +
 +
 +bool merge_topaz_reader_frames(uint32_t timestamp, uint32_t *duration, uint16_t *tracepos, uint16_t traceLen, uint8_t *trace, uint8_t *frame, uint8_t *topaz_reader_command, uint16_t *data_len)
 +{
 +
 +#define MAX_TOPAZ_READER_CMD_LEN      16
 +
 +      uint32_t last_timestamp = timestamp + *duration;
 +
 +      if ((*data_len != 1) || (frame[0] == TOPAZ_WUPA) || (frame[0] == TOPAZ_REQA)) return false;
  
 +      memcpy(topaz_reader_command, frame, *data_len);
 +
 +      while (!is_last_record(*tracepos, trace, traceLen) && !next_record_is_response(*tracepos, trace)) {
 +              uint32_t next_timestamp = *((uint32_t *)(trace + *tracepos));
 +              *tracepos += sizeof(uint32_t);
 +              uint16_t next_duration = *((uint16_t *)(trace + *tracepos));
 +              *tracepos += sizeof(uint16_t);
 +              uint16_t next_data_len = *((uint16_t *)(trace + *tracepos)) & 0x7FFF;
 +              *tracepos += sizeof(uint16_t);
 +              uint8_t *next_frame = (trace + *tracepos);
 +              *tracepos += next_data_len;
 +              if ((next_data_len == 1) && (*data_len + next_data_len <= MAX_TOPAZ_READER_CMD_LEN)) {
 +                      memcpy(topaz_reader_command + *data_len, next_frame, next_data_len);
 +                      *data_len += next_data_len;
 +                      last_timestamp = next_timestamp + next_duration;
 +              } else {
 +                      // rewind and exit
 +                      *tracepos = *tracepos - next_data_len - sizeof(uint16_t) - sizeof(uint16_t) - sizeof(uint32_t);
 +                      break;
 +              }
 +              uint16_t next_parity_len = (next_data_len-1)/8 + 1;
 +              *tracepos += next_parity_len;
 +      }
 +
 +      *duration = last_timestamp - timestamp;
 +      
 +      return true;
 +}
 +
 +
 +uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, uint8_t protocol, bool showWaitCycles, bool markCRCBytes)
 +{
 +      bool isResponse;
 +      uint16_t data_len, parity_len;
 +      uint32_t duration;
 +      uint8_t topaz_reader_command[9];
        uint32_t timestamp, first_timestamp, EndOfTransmissionTimestamp;
        char explanation[30] = {0};
  
        uint8_t *parityBytes = trace + tracepos;
        tracepos += parity_len;
  
 +      if (protocol == TOPAZ && !isResponse) {
 +              // topaz reader commands come in 1 or 9 separate frames with 7 or 8 Bits each.
 +              // merge them:
 +              if (merge_topaz_reader_frames(timestamp, &duration, &tracepos, traceLen, trace, frame, topaz_reader_command, &data_len)) {
 +                      frame = topaz_reader_command;
 +              }
 +      }
 +      
        //Check the CRC status
        uint8_t crcStatus = 2;
  
        if (data_len > 2) {
 -              uint8_t b1, b2;
 -              if(protocol == ICLASS)
 -              {
 -                      crcStatus = iclass_CRC_check(isResponse, frame, data_len);
 -
 -              }else if (protocol == ISO_14443B)
 -              {
 -                      crcStatus = iso14443B_CRC_check(isResponse, frame, data_len);
 -              }
 -              else if (protocol == ISO_14443A){//Iso 14443a
 -
 -                      ComputeCrc14443(CRC_14443_A, frame, data_len-2, &b1, &b2);
 -
 -                      if (b1 != frame[data_len-2] || b2 != frame[data_len-1]) {
 -                              if(!(isResponse & (data_len < 6)))
 -                              {
 -                                              crcStatus = 0;
 -                              }
 -                      }
 +              switch (protocol) {
 +                      case ICLASS:
 +                              crcStatus = iclass_CRC_check(isResponse, frame, data_len);
 +                              break;
 +                      case ISO_14443B:
 +                      case TOPAZ:
 +                              crcStatus = iso14443B_CRC_check(isResponse, frame, data_len); 
 +                              break;
 +                      case ISO_14443A:
 +                              crcStatus = iso14443A_CRC_check(isResponse, frame, data_len);
 +                              break;
 +                      default: 
 +                              break;
                }
        }
        //0 CRC-command, CRC not ok
                        oddparity ^= (((frame[j] & 0xFF) >> k) & 0x01);
                }
                uint8_t parityBits = parityBytes[j>>3];
-               if (protocol != ISO_14443B && isResponse && (oddparity != ((parityBits >> (7-(j&0x0007))) & 0x01))) {
+               if (protocol != ISO_14443B && (isResponse || protocol == ISO_14443A) && (oddparity != ((parityBits >> (7-(j&0x0007))) & 0x01))) {
                        snprintf(line[j/16]+(( j % 16) * 4),110, "%02x! ", frame[j]);
 -
                } else {
 -                      snprintf(line[j/16]+(( j % 16) * 4),110, "%02x  ", frame[j]);
 +                      snprintf(line[j/16]+(( j % 16) * 4), 110, " %02x ", frame[j]);
                }
  
        }
 -      if(crcStatus == 1)
 -      {//CRC-command
 -              char *pos1 = line[(data_len-2)/16]+(((data_len-2) % 16) * 4)-1;
 -              (*pos1) = '[';
 -              char *pos2 = line[(data_len)/16]+(((data_len) % 16) * 4)-2;
 -              (*pos2) = ']';
 +
 +      if (markCRCBytes) {
 +              if(crcStatus == 0 || crcStatus == 1)
 +              {//CRC-command
 +                      char *pos1 = line[(data_len-2)/16]+(((data_len-2) % 16) * 4);
 +                      (*pos1) = '[';
 +                      char *pos2 = line[(data_len)/16]+(((data_len) % 16) * 4);
 +                      sprintf(pos2, "%c", ']');
 +              }
        }
 +
        if(data_len == 0)
        {
                if(data_len == 0){
  
        if(!isResponse)
        {
 -              if(protocol == ICLASS)
 -                      annotateIclass(explanation,sizeof(explanation),frame,data_len);
 -              else if (protocol == ISO_14443A)
 -                      annotateIso14443a(explanation,sizeof(explanation),frame,data_len);
 -              else if(protocol == ISO_14443B)
 -                      annotateIso14443b(explanation,sizeof(explanation),frame,data_len);
 +              switch(protocol) {
 +                      case ICLASS:            annotateIclass(explanation,sizeof(explanation),frame,data_len); break;
 +                      case ISO_14443A:        annotateIso14443a(explanation,sizeof(explanation),frame,data_len); break;
 +                      case ISO_14443B:        annotateIso14443b(explanation,sizeof(explanation),frame,data_len); break;
 +                      case TOPAZ:                     annotateTopaz(explanation,sizeof(explanation),frame,data_len); break;
 +                      default:                        break;
 +              }
        }
  
        int num_lines = MIN((data_len - 1)/16 + 1, 16);
        for (int j = 0; j < num_lines ; j++) {
                if (j == 0) {
 -                      PrintAndLog(" %9d | %9d | %s | %-64s| %s| %s",
 +                      PrintAndLog(" %10d | %10d | %s |%-64s | %s| %s",
                                (timestamp - first_timestamp),
                                (EndOfTransmissionTimestamp - first_timestamp),
                                (isResponse ? "Tag" : "Rdr"),
                                (j == num_lines-1) ? crc : "    ",
                                (j == num_lines-1) ? explanation : "");
                } else {
 -                      PrintAndLog("           |           |     | %-64s| %s| %s",
 +                      PrintAndLog("            |            |     |%-64s | %s| %s",
                                line[j],
 -                              (j == num_lines-1)?crc:"    ",
 +                              (j == num_lines-1) ? crc : "    ",
                                (j == num_lines-1) ? explanation : "");
                }
        }
  
 -      if (tracepos + sizeof(uint32_t) + sizeof(uint16_t) + sizeof(uint16_t) > traceLen) return traceLen;
 +      if (is_last_record(tracepos, trace, traceLen)) return traceLen;
        
 -      bool next_isResponse = *((uint16_t *)(trace + tracepos + 6)) & 0x8000;
 -
 -      if (showWaitCycles && !isResponse && next_isResponse) {
 +      if (showWaitCycles && !isResponse && next_record_is_response(tracepos, trace)) {
                uint32_t next_timestamp = *((uint32_t *)(trace + tracepos));
 -              if (next_timestamp != 0x44444444) {
 -                      PrintAndLog(" %9d | %9d | %s | fdt (Frame Delay Time): %d",
 -                              (EndOfTransmissionTimestamp - first_timestamp),
 -                              (next_timestamp - first_timestamp),
 -                              "   ",
 -                              (next_timestamp - EndOfTransmissionTimestamp));
 -              }
 +              PrintAndLog(" %9d | %9d | %s | fdt (Frame Delay Time): %d",
 +                      (EndOfTransmissionTimestamp - first_timestamp),
 +                      (next_timestamp - first_timestamp),
 +                      "   ",
 +                      (next_timestamp - EndOfTransmissionTimestamp));
        }
  
        return tracepos;
  int CmdHFList(const char *Cmd)
  {
        bool showWaitCycles = false;
 +      bool markCRCBytes = false;
        char type[40] = {0};
        int tlen = param_getstr(Cmd,0,type);
 -      char param = param_getchar(Cmd, 1);
 +      char param1 = param_getchar(Cmd, 1);
 +      char param2 = param_getchar(Cmd, 2);
        bool errors = false;
        uint8_t protocol = 0;
        //Validate params
 -      if(tlen == 0)
 -      {
 +
 +      if(tlen == 0) {
                errors = true;
        }
 -      if(param == 'h' || (param !=0 && param != 'f'))
 -      {
 +
 +      if(param1 == 'h'
 +                      || (param1 != 0 && param1 != 'f' && param1 != 'c')
 +                      || (param2 != 0 && param2 != 'f' && param2 != 'c')) {
                errors = true;
        }
 -      if(!errors)
 -      {
 -              if(strcmp(type, "iclass") == 0)
 -              {
 +
 +      if(!errors) {
 +              if(strcmp(type, "iclass") == 0) {
                        protocol = ICLASS;
 -              }else if(strcmp(type, "14a") == 0)
 -              {
 +              } else if(strcmp(type, "14a") == 0) {
                        protocol = ISO_14443A;
 -              }
 -              else if(strcmp(type, "14b") == 0)
 -              {
 +              } else if(strcmp(type, "14b") == 0)     {
                        protocol = ISO_14443B;
 -              }else if(strcmp(type,"raw")== 0)
 -              {
 +              } else if(strcmp(type,"topaz")== 0) {
 +                      protocol = TOPAZ;
 +              } else if(strcmp(type,"raw")== 0) {
                        protocol = -1;//No crc, no annotations
 -              }else{
 +              } else {
                        errors = true;
                }
        }
  
        if (errors) {
                PrintAndLog("List protocol data in trace buffer.");
 -              PrintAndLog("Usage:  hf list <protocol> [f]");
 +              PrintAndLog("Usage:  hf list <protocol> [f][c]");
                PrintAndLog("    f      - show frame delay times as well");
 +              PrintAndLog("    c      - mark CRC bytes");
                PrintAndLog("Supported <protocol> values:");
                PrintAndLog("    raw    - just show raw data without annotations");
                PrintAndLog("    14a    - interpret data as iso14443a communications");
                PrintAndLog("    14b    - interpret data as iso14443b communications");
                PrintAndLog("    iclass - interpret data as iclass communications");
 +              PrintAndLog("    topaz  - interpret data as topaz communications");
                PrintAndLog("");
                PrintAndLog("example: hf list 14a f");
                PrintAndLog("example: hf list iclass");
        }
  
  
 -      if (param == 'f') {
 +      if (param1 == 'f' || param2 == 'f') {
                showWaitCycles = true;
        }
  
 +      if (param1 == 'c' || param2 == 'c') {
 +              markCRCBytes = true;
 +      }
  
        uint8_t *trace;
        uint16_t tracepos = 0;
        PrintAndLog("iso14443a - All times are in carrier periods (1/13.56Mhz)");
        PrintAndLog("iClass    - Timings are not as accurate");
        PrintAndLog("");
 -      PrintAndLog("     Start |       End | Src | Data (! denotes parity error)                                   | CRC | Annotation         |");
 -      PrintAndLog("-----------|-----------|-----|-----------------------------------------------------------------|-----|--------------------|");
 +      PrintAndLog("      Start |        End | Src | Data (! denotes parity error)                                   | CRC | Annotation         |");
 +      PrintAndLog("------------|------------|-----|-----------------------------------------------------------------|-----|--------------------|");
  
        while(tracepos < traceLen)
        {
 -              tracepos = printTraceLine(tracepos, traceLen, trace, protocol, showWaitCycles);
 +              tracepos = printTraceLine(tracepos, traceLen, trace, protocol, showWaitCycles, markCRCBytes);
        }
  
        free(trace);
@@@ -690,21 -578,6 +690,21 @@@ int CmdHFSearch(const char *Cmd)
  
  static command_t CommandTable[] = 
  {
 +<<<<<<< HEAD
 +      {"help",        CmdHelp,                1, "This help"},
 +      {"14a",         CmdHF14A,               1, "{ ISO14443A RFIDs... }"},
 +      {"14b",         CmdHF14B,               1, "{ ISO14443B RFIDs... }"},
 +      {"15",          CmdHF15,                1, "{ ISO15693 RFIDs... }"},
 +      {"epa",         CmdHFEPA,               1, "{ German Identification Card... }"},
 +      {"legic",       CmdHFLegic,             0, "{ LEGIC RFIDs... }"},
 +      {"iclass",      CmdHFiClass,    1, "{ ICLASS RFIDs... }"},
 +      {"mf",          CmdHFMF,                1, "{ MIFARE RFIDs... }"},
 +      {"mfu",         CmdHFMFUltra,   1, "{ MIFARE Ultralight RFIDs... }"},
 +      {"topaz",       CmdHFTopaz,             1, "{ TOPAZ (NFC Type 1) RFIDs... }"},
 +      {"tune",        CmdHFTune,              0, "Continuously measure HF antenna tuning"},
 +      {"list",        CmdHFList,              1, "List protocol data in trace buffer"},
 +      {NULL,          NULL,                   0, NULL}
 +=======
    {"help",        CmdHelp,          1, "This help"},
    {"14a",         CmdHF14A,         1, "{ ISO14443A RFIDs... }"},
    {"14b",         CmdHF14B,         1, "{ ISO14443B RFIDs... }"},
    {"list",        CmdHFList,        1, "List protocol data in trace buffer"},
    {"search",      CmdHFSearch,      1, "Search for known HF tags [preliminary]"},
        {NULL, NULL, 0, NULL}
 +>>>>>>> master
  };
  
  int CmdHF(const char *Cmd)
Impressum, Datenschutz