]> git.zerfleddert.de Git - proxmark3-svn/commitdiff
Merge remote-tracking branch 'upstream/master'
authormarshmellow42 <marshmellowrf@gmail.com>
Thu, 16 Jul 2015 02:25:11 +0000 (22:25 -0400)
committermarshmellow42 <marshmellowrf@gmail.com>
Thu, 16 Jul 2015 02:25:11 +0000 (22:25 -0400)
Conflicts:
armsrc/iso14443b.c

1  2 
CHANGELOG.md
armsrc/iso14443b.c

diff --combined CHANGELOG.md
index 75b9ad9b5616e6c755ed54764e59994ae927cca7,b0135cc28195a3b3eb00ab845a247096ec9e3c8e..42b6bcbeb1cde0f845d9dc45763a12cced15ef45
@@@ -2,12 -2,18 +2,19 @@@
  All notable changes to this project will be documented in this file.
  This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
  
- ## [Unreleased][unreleased]
+ ## [unreleased][unreleased]
+ ### Changed
+ - EPA functions (`hf epa`) now support both ISO 14443-A and 14443-B cards (frederikmoellers)
+ ## [2.2.0][2015-07-12]
  
  ### Changed
 +- Added `hf 14b raw -s` option to auto select a 14b std tag before raw command 
  - Changed `hf 14b write` to `hf 14b sriwrite` as it only applied to sri tags (marshmellow)
  - Added `hf 14b info` to `hf search` (marshmellow)
+ - Added compression of fpga config and data, *BOOTROM REFLASH REQUIRED* (piwi)
+ - Implemented better detection of mifare-tags that are not vulnerable to classic attacks (`hf mf mifare`, `hf mf nested`) (piwi)
  
  ### Added
  - Add `hf 14b info` to find and print info about std 14b tags and sri tags (using 14b raw commands in the client)  (marshmellow)
diff --combined armsrc/iso14443b.c
index bfbd7bf59ce1aa18defc1037127aaf2a0a16c679,f8e6046ca487b20d24b071e549b98e77df4cd49b..82e5dd6a1c1bba44a33814b62b06be2d1e047093
@@@ -19,6 -19,9 +19,9 @@@
  #define RECEIVE_SAMPLES_TIMEOUT 2000
  #define ISO14443B_DMA_BUFFER_SIZE 256
  
+ // PCB Block number for APDUs
+ static uint8_t pcb_blocknum = 0;
  //=============================================================================
  // An ISO 14443 Type B tag. We listen for commands from the reader, using
  // a UART kind of thing that's implemented in software. When we get a
@@@ -311,7 -314,7 +314,7 @@@ static int GetIso14443bCommandFromReade
                        }
                }
        }
-       
        return FALSE;
  }
  
  //-----------------------------------------------------------------------------
  void SimulateIso14443bTag(void)
  {
 -      // the only commands we understand is REQB, AFI=0, Select All, N=0:
 -      static const uint8_t cmd1[] = { 0x05, 0x00, 0x08, 0x39, 0x73 };
 -      // ... and REQB, AFI=0, Normal Request, N=0:
 -      static const uint8_t cmd2[] = { 0x05, 0x00, 0x00, 0x71, 0xFF };
 +      // the only commands we understand is WUPB, AFI=0, Select All, N=1:
 +      static const uint8_t cmd1[] = { 0x05, 0x00, 0x08, 0x39, 0x73 }; // WUPB
 +      // ... and REQB, AFI=0, Normal Request, N=1:
 +      static const uint8_t cmd2[] = { 0x05, 0x00, 0x00, 0x71, 0xFF }; // REQB
 +      // ... and HLTB
 +      static const uint8_t cmd3[] = { 0x50, 0xff, 0xff, 0xff, 0xff }; // HLTB
 +      // ... and ATTRIB
 +      static const uint8_t cmd4[] = { 0x1D, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; // ATTRIB
  
        // ... and we always respond with ATQB, PUPI = 820de174, Application Data = 0x20381922,
        // supports only 106kBit/s in both directions, max frame size = 32Bytes,
                0x50, 0x82, 0x0d, 0xe1, 0x74, 0x20, 0x38, 0x19, 0x22,
                0x00, 0x21, 0x85, 0x5e, 0xd7
        };
 +      // response to HLTB and ATTRIB
 +      static const uint8_t response2[] = {0x00, 0x78, 0xF0};
 +
  
        FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
  
        memcpy(resp1Code, ToSend, ToSendMax);
        uint16_t resp1CodeLen = ToSendMax;
  
 +      // prepare the (other) tag answer:
 +      CodeIso14443bAsTag(response2, sizeof(response2));
 +      uint8_t *resp2Code = BigBuf_malloc(ToSendMax);
 +      memcpy(resp2Code, ToSend, ToSendMax);
 +      uint16_t resp2CodeLen = ToSendMax;
 +
        // We need to listen to the high-frequency, peak-detected path.
        SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
        FpgaSetupSsc();
                        respLen = sizeof(response1);
                        respCode = resp1Code;
                        respCodeLen = resp1CodeLen;
 +              } else if ( (len == sizeof(cmd3) && receivedCmd[0] == cmd3[0])
 +                      || (len == sizeof(cmd4) && receivedCmd[0] == cmd4[0]) ) {
 +                      resp = response2;
 +                      respLen = sizeof(response2);
 +                      respCode = resp2Code;
 +                      respCodeLen = resp2CodeLen;
                } else {
                        Dbprintf("new cmd from reader: len=%d, cmdsRecvd=%d", len, cmdsRecvd);
                        // And print whether the CRC fails, just for good measure
                        uint8_t b1, b2;
 -                      ComputeCrc14443(CRC_14443_B, receivedCmd, len-2, &b1, &b2);
 -                      if(b1 != receivedCmd[len-2] || b2 != receivedCmd[len-1]) {
 -                              // Not so good, try again.
 -                              DbpString("+++CRC fail");
 -                      } else {
 -                              DbpString("CRC passes");
 +                      if (len >= 3){ // if crc exists
 +                              ComputeCrc14443(CRC_14443_B, receivedCmd, len-2, &b1, &b2);
 +                              if(b1 != receivedCmd[len-2] || b2 != receivedCmd[len-1]) {
 +                                      // Not so good, try again.
 +                                      DbpString("+++CRC fail");
 +              
 +                              } else {
 +                                      DbpString("CRC passes");
 +                              }
                        }
 -                      break;
 +                      //get rid of compiler warning
 +                      respCodeLen = 0;
 +                      resp = response1;
 +                      respLen = 0;
 +                      respCode = resp1Code;
 +                      //don't crash at new command just wait and see if reader will send other new cmds.
 +                      //break;
                }
  
                cmdsRecvd++;
@@@ -924,6 -899,98 +927,98 @@@ static void CodeAndTransmit14443bAsRead
        }
  }
  
+ /* Sends an APDU to the tag
+  * TODO: check CRC and preamble
+  */
+ int iso14443b_apdu(uint8_t const *message, size_t message_length, uint8_t *response)
+ {
+       uint8_t message_frame[message_length + 4];
+       // PCB
+       message_frame[0] = 0x0A | pcb_blocknum;
+       pcb_blocknum ^= 1;
+       // CID
+       message_frame[1] = 0;
+       // INF
+       memcpy(message_frame + 2, message, message_length);
+       // EDC (CRC)
+       ComputeCrc14443(CRC_14443_B, message_frame, message_length + 2, &message_frame[message_length + 2], &message_frame[message_length + 3]);
+       // send
+       CodeAndTransmit14443bAsReader(message_frame, message_length + 4);
+       // get response
+       GetSamplesFor14443bDemod(RECEIVE_SAMPLES_TIMEOUT*100, TRUE);
+       if(Demod.len < 3)
+       {
+               return 0;
+       }
+       // TODO: Check CRC
+       // copy response contents
+       if(response != NULL)
+       {
+               memcpy(response, Demod.output, Demod.len);
+       }
+       return Demod.len;
+ }
+ /* Perform the ISO 14443 B Card Selection procedure
+  * Currently does NOT do any collision handling.
+  * It expects 0-1 cards in the device's range.
+  * TODO: Support multiple cards (perform anticollision)
+  * TODO: Verify CRC checksums
+  */
+ int iso14443b_select_card()
+ {
+       // WUPB command (including CRC)
+       // Note: WUPB wakes up all tags, REQB doesn't wake up tags in HALT state
+       static const uint8_t wupb[] = { 0x05, 0x00, 0x08, 0x39, 0x73 };
+       // ATTRIB command (with space for CRC)
+       uint8_t attrib[] = { 0x1D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00};
+       // first, wake up the tag
+       CodeAndTransmit14443bAsReader(wupb, sizeof(wupb));
+       GetSamplesFor14443bDemod(RECEIVE_SAMPLES_TIMEOUT, TRUE);
+       // ATQB too short?
+       if (Demod.len < 14)
+       {
+               return 2;
+       }
+     // select the tag
+     // copy the PUPI to ATTRIB
+     memcpy(attrib + 1, Demod.output + 1, 4);
+     /* copy the protocol info from ATQB (Protocol Info -> Protocol_Type) into
+     ATTRIB (Param 3) */
+     attrib[7] = Demod.output[10] & 0x0F;
+     ComputeCrc14443(CRC_14443_B, attrib, 9, attrib + 9, attrib + 10);
+     CodeAndTransmit14443bAsReader(attrib, sizeof(attrib));
+     GetSamplesFor14443bDemod(RECEIVE_SAMPLES_TIMEOUT, TRUE);
+     // Answer to ATTRIB too short?
+     if(Demod.len < 3)
+       {
+               return 2;
+       }
+       // reset PCB block number
+       pcb_blocknum = 0;
+       return 1;
+ }
+ // Set up ISO 14443 Type B communication (similar to iso14443a_setup)
+ void iso14443b_setup() {
+       FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
+       // Set up the synchronous serial port
+       FpgaSetupSsc();
+       // connect Demodulated Signal to ADC:
+       SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
+       // Signal field is on with the appropriate LED
+     LED_D_ON();
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX | FPGA_HF_READER_TX_SHALLOW_MOD);
+       // Start the timer
+       StartCountSspClk();
+       DemodReset();
+       UartReset();
+ }
  
  //-----------------------------------------------------------------------------
  // Read a SRI512 ISO 14443B tag.
@@@ -1228,16 -1295,14 +1323,16 @@@ void SendRawCommand14443B(uint32_t data
        SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
        FpgaSetupSsc();
  
 -      set_tracing(TRUE);
 -
 -      CodeAndTransmit14443bAsReader(data, datalen);
 +      if (datalen){
 +              set_tracing(TRUE);
 +              
 +              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);
 +              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);
 +              }
        }
  
        if(!powerfield) {
Impressum, Datenschutz