-//-----------------------------------------------------------------------------\r
-// Routines to support ISO 14443. This includes both the reader software and\r
-// the `fake tag' modes. At the moment only the Type B modulation is\r
-// supported.\r
-// Jonathan Westhues, split Nov 2006\r
-//-----------------------------------------------------------------------------\r
-#include <proxmark3.h>\r
-#include "apps.h"\r
-#include "../common/iso14443_crc.c"\r
-\r
-\r
-//static void GetSamplesFor14443(BOOL weTx, int n);\r
-\r
-#define DMA_BUFFER_SIZE 256\r
-\r
-//=============================================================================\r
-// An ISO 14443 Type B tag. We listen for commands from the reader, using\r
-// a UART kind of thing that's implemented in software. When we get a\r
-// frame (i.e., a group of bytes between SOF and EOF), we check the CRC.\r
-// If it's good, then we can do something appropriate with it, and send\r
-// a response.\r
-//=============================================================================\r
-\r
-//-----------------------------------------------------------------------------\r
-// Code up a string of octets at layer 2 (including CRC, we don't generate\r
-// that here) so that they can be transmitted to the reader. Doesn't transmit\r
-// them yet, just leaves them ready to send in ToSend[].\r
-//-----------------------------------------------------------------------------\r
-static void CodeIso14443bAsTag(const BYTE *cmd, int len)\r
-{\r
- int i;\r
-\r
- ToSendReset();\r
-\r
- // Transmit a burst of ones, as the initial thing that lets the\r
- // reader get phase sync. This (TR1) must be > 80/fs, per spec,\r
- // but tag that I've tried (a Paypass) exceeds that by a fair bit,\r
- // so I will too.\r
- for(i = 0; i < 20; i++) {\r
- ToSendStuffBit(1);\r
- ToSendStuffBit(1);\r
- ToSendStuffBit(1);\r
- ToSendStuffBit(1);\r
- }\r
-\r
- // Send SOF.\r
- for(i = 0; i < 10; i++) {\r
- ToSendStuffBit(0);\r
- ToSendStuffBit(0);\r
- ToSendStuffBit(0);\r
- ToSendStuffBit(0);\r
- }\r
- for(i = 0; i < 2; i++) {\r
- ToSendStuffBit(1);\r
- ToSendStuffBit(1);\r
- ToSendStuffBit(1);\r
- ToSendStuffBit(1);\r
- }\r
-\r
- for(i = 0; i < len; i++) {\r
- int j;\r
- BYTE b = cmd[i];\r
-\r
- // Start bit\r
- ToSendStuffBit(0);\r
- ToSendStuffBit(0);\r
- ToSendStuffBit(0);\r
- ToSendStuffBit(0);\r
-\r
- // Data bits\r
- for(j = 0; j < 8; j++) {\r
- if(b & 1) {\r
- ToSendStuffBit(1);\r
- ToSendStuffBit(1);\r
- ToSendStuffBit(1);\r
- ToSendStuffBit(1);\r
- } else {\r
- ToSendStuffBit(0);\r
- ToSendStuffBit(0);\r
- ToSendStuffBit(0);\r
- ToSendStuffBit(0);\r
- }\r
- b >>= 1;\r
- }\r
-\r
- // Stop bit\r
- ToSendStuffBit(1);\r
- ToSendStuffBit(1);\r
- ToSendStuffBit(1);\r
- ToSendStuffBit(1);\r
- }\r
-\r
- // Send SOF.\r
- for(i = 0; i < 10; i++) {\r
- ToSendStuffBit(0);\r
- ToSendStuffBit(0);\r
- ToSendStuffBit(0);\r
- ToSendStuffBit(0);\r
- }\r
- for(i = 0; i < 10; i++) {\r
- ToSendStuffBit(1);\r
- ToSendStuffBit(1);\r
- ToSendStuffBit(1);\r
- ToSendStuffBit(1);\r
- }\r
-\r
- // Convert from last byte pos to length\r
- ToSendMax++;\r
-\r
- // Add a few more for slop\r
- ToSendMax += 2;\r
-}\r
-\r
-//-----------------------------------------------------------------------------\r
-// The software UART that receives commands from the reader, and its state\r
-// variables.\r
-//-----------------------------------------------------------------------------\r
-static struct {\r
- enum {\r
- STATE_UNSYNCD,\r
- STATE_GOT_FALLING_EDGE_OF_SOF,\r
- STATE_AWAITING_START_BIT,\r
- STATE_RECEIVING_DATA,\r
- STATE_ERROR_WAIT\r
- } state;\r
- WORD shiftReg;\r
- int bitCnt;\r
- int byteCnt;\r
- int byteCntMax;\r
- int posCnt;\r
- BYTE *output;\r
-} Uart;\r
-\r
-/* Receive & handle a bit coming from the reader.\r
- *\r
- * LED handling:\r
- * LED A -> ON once we have received the SOF and are expecting the rest.\r
- * LED A -> OFF once we have received EOF or are in error state or unsynced\r
- *\r
- * Returns: true if we received a EOF\r
- * false if we are still waiting for some more\r
- */\r
-static BOOL Handle14443UartBit(int bit)\r
-{\r
- switch(Uart.state) {\r
- case STATE_UNSYNCD:\r
- LED_A_OFF();\r
- if(!bit) {\r
- // we went low, so this could be the beginning\r
- // of an SOF\r
- Uart.state = STATE_GOT_FALLING_EDGE_OF_SOF;\r
- Uart.posCnt = 0;\r
- Uart.bitCnt = 0;\r
- }\r
- break;\r
-\r
- case STATE_GOT_FALLING_EDGE_OF_SOF:\r
- Uart.posCnt++;\r
- if(Uart.posCnt == 2) {\r
- if(bit) {\r
- if(Uart.bitCnt >= 10) {\r
- // we've seen enough consecutive\r
- // zeros that it's a valid SOF\r
- Uart.posCnt = 0;\r
- Uart.byteCnt = 0;\r
- Uart.state = STATE_AWAITING_START_BIT;\r
- LED_A_ON(); // Indicate we got a valid SOF\r
- } else {\r
- // didn't stay down long enough\r
- // before going high, error\r
- Uart.state = STATE_ERROR_WAIT;\r
- }\r
- } else {\r
- // do nothing, keep waiting\r
- }\r
- Uart.bitCnt++;\r
- }\r
- if(Uart.posCnt >= 4) Uart.posCnt = 0;\r
- if(Uart.bitCnt > 14) {\r
- // Give up if we see too many zeros without\r
- // a one, too.\r
- Uart.state = STATE_ERROR_WAIT;\r
- }\r
- break;\r
-\r
- case STATE_AWAITING_START_BIT:\r
- Uart.posCnt++;\r
- if(bit) {\r
- if(Uart.posCnt > 25) {\r
- // stayed high for too long between\r
- // characters, error\r
- Uart.state = STATE_ERROR_WAIT;\r
- }\r
- } else {\r
- // falling edge, this starts the data byte\r
- Uart.posCnt = 0;\r
- Uart.bitCnt = 0;\r
- Uart.shiftReg = 0;\r
- Uart.state = STATE_RECEIVING_DATA;\r
- LED_A_ON(); // Indicate we're receiving\r
- }\r
- break;\r
-\r
- case STATE_RECEIVING_DATA:\r
- Uart.posCnt++;\r
- if(Uart.posCnt == 2) {\r
- // time to sample a bit\r
- Uart.shiftReg >>= 1;\r
- if(bit) {\r
- Uart.shiftReg |= 0x200;\r
- }\r
- Uart.bitCnt++;\r
- }\r
- if(Uart.posCnt >= 4) {\r
- Uart.posCnt = 0;\r
- }\r
- if(Uart.bitCnt == 10) {\r
- if((Uart.shiftReg & 0x200) && !(Uart.shiftReg & 0x001))\r
- {\r
- // this is a data byte, with correct\r
- // start and stop bits\r
- Uart.output[Uart.byteCnt] = (Uart.shiftReg >> 1) & 0xff;\r
- Uart.byteCnt++;\r
-\r
- if(Uart.byteCnt >= Uart.byteCntMax) {\r
- // Buffer overflowed, give up\r
- Uart.posCnt = 0;\r
- Uart.state = STATE_ERROR_WAIT;\r
- } else {\r
- // so get the next byte now\r
- Uart.posCnt = 0;\r
- Uart.state = STATE_AWAITING_START_BIT;\r
- }\r
- } else if(Uart.shiftReg == 0x000) {\r
- // this is an EOF byte\r
- LED_A_OFF(); // Finished receiving\r
- return TRUE;\r
- } else {\r
- // this is an error\r
- Uart.posCnt = 0;\r
- Uart.state = STATE_ERROR_WAIT;\r
- }\r
- }\r
- break;\r
-\r
- case STATE_ERROR_WAIT:\r
- // We're all screwed up, so wait a little while\r
- // for whatever went wrong to finish, and then\r
- // start over.\r
- Uart.posCnt++;\r
- if(Uart.posCnt > 10) {\r
- Uart.state = STATE_UNSYNCD;\r
- }\r
- break;\r
-\r
- default:\r
- Uart.state = STATE_UNSYNCD;\r
- break;\r
- }\r
-\r
- if (Uart.state == STATE_ERROR_WAIT) LED_A_OFF(); // Error\r
-\r
- return FALSE;\r
-}\r
-\r
-//-----------------------------------------------------------------------------\r
-// Receive a command (from the reader to us, where we are the simulated tag),\r
-// and store it in the given buffer, up to the given maximum length. Keeps\r
-// spinning, waiting for a well-framed command, until either we get one\r
-// (returns TRUE) or someone presses the pushbutton on the board (FALSE).\r
-//\r
-// Assume that we're called with the SSC (to the FPGA) and ADC path set\r
-// correctly.\r
-//-----------------------------------------------------------------------------\r
-static BOOL GetIso14443CommandFromReader(BYTE *received, int *len, int maxLen)\r
-{\r
- BYTE mask;\r
- int i, bit;\r
-\r
- // Set FPGA mode to "simulated ISO 14443 tag", no modulation (listen\r
- // only, since we are receiving, not transmitting).\r
- // Signal field is off with the appropriate LED\r
- LED_D_OFF();\r
- FpgaWriteConfWord(\r
- FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_NO_MODULATION);\r
-\r
-\r
- // Now run a `software UART' on the stream of incoming samples.\r
- Uart.output = received;\r
- Uart.byteCntMax = maxLen;\r
- Uart.state = STATE_UNSYNCD;\r
-\r
- for(;;) {\r
- WDT_HIT();\r
-\r
- if(BUTTON_PRESS()) return FALSE;\r
-\r
- if(SSC_STATUS & (SSC_STATUS_TX_READY)) {\r
- SSC_TRANSMIT_HOLDING = 0x00;\r
- }\r
- if(SSC_STATUS & (SSC_STATUS_RX_READY)) {\r
- BYTE b = (BYTE)SSC_RECEIVE_HOLDING;\r
-\r
- mask = 0x80;\r
- for(i = 0; i < 8; i++, mask >>= 1) {\r
- bit = (b & mask);\r
- if(Handle14443UartBit(bit)) {\r
- *len = Uart.byteCnt;\r
- return TRUE;\r
- }\r
- }\r
- }\r
- }\r
-}\r
-\r
-//-----------------------------------------------------------------------------\r
-// Main loop of simulated tag: receive commands from reader, decide what\r
-// response to send, and send it.\r
-//-----------------------------------------------------------------------------\r
-void SimulateIso14443Tag(void)\r
-{\r
- static const BYTE cmd1[] = { 0x05, 0x00, 0x08, 0x39, 0x73 };\r
- static const BYTE response1[] = {\r
- 0x50, 0x82, 0x0d, 0xe1, 0x74, 0x20, 0x38, 0x19, 0x22,\r
- 0x00, 0x21, 0x85, 0x5e, 0xd7\r
- };\r
-\r
- BYTE *resp;\r
- int respLen;\r
-\r
- BYTE *resp1 = (((BYTE *)BigBuf) + 800);\r
- int resp1Len;\r
-\r
- BYTE *receivedCmd = (BYTE *)BigBuf;\r
- int len;\r
-\r
- int i;\r
-\r
- int cmdsRecvd = 0;\r
-\r
- memset(receivedCmd, 0x44, 400);\r
-\r
- CodeIso14443bAsTag(response1, sizeof(response1));\r
- memcpy(resp1, ToSend, ToSendMax); resp1Len = ToSendMax;\r
-\r
- // We need to listen to the high-frequency, peak-detected path.\r
- SetAdcMuxFor(GPIO_MUXSEL_HIPKD);\r
- FpgaSetupSsc();\r
-\r
- cmdsRecvd = 0;\r
-\r
- for(;;) {\r
- BYTE b1, b2;\r
-\r
- if(!GetIso14443CommandFromReader(receivedCmd, &len, 100)) {\r
- DbpIntegers(cmdsRecvd, 0, 0);\r
- DbpString("button press");\r
- break;\r
- }\r
-\r
- // Good, look at the command now.\r
-\r
- if(len == sizeof(cmd1) && memcmp(receivedCmd, cmd1, len)==0) {\r
- resp = resp1; respLen = resp1Len;\r
- } else {\r
- DbpString("new cmd from reader:");\r
- DbpIntegers(len, 0x1234, cmdsRecvd);\r
- // And print whether the CRC fails, just for good measure\r
- ComputeCrc14443(CRC_14443_B, receivedCmd, len-2, &b1, &b2);\r
- if(b1 != receivedCmd[len-2] || b2 != receivedCmd[len-1]) {\r
- // Not so good, try again.\r
- DbpString("+++CRC fail");\r
- } else {\r
- DbpString("CRC passes");\r
- }\r
- break;\r
- }\r
-\r
- memset(receivedCmd, 0x44, 32);\r
-\r
- cmdsRecvd++;\r
-\r
- if(cmdsRecvd > 0x30) {\r
- DbpString("many commands later...");\r
- break;\r
- }\r
-\r
- if(respLen <= 0) continue;\r
-\r
- // Modulate BPSK\r
- // Signal field is off with the appropriate LED\r
- LED_D_OFF();\r
- FpgaWriteConfWord(\r
- FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_MODULATE_BPSK);\r
- SSC_TRANSMIT_HOLDING = 0xff;\r
- FpgaSetupSsc();\r
-\r
- // Transmit the response.\r
- i = 0;\r
- for(;;) {\r
- if(SSC_STATUS & (SSC_STATUS_TX_READY)) {\r
- BYTE b = resp[i];\r
-\r
- SSC_TRANSMIT_HOLDING = b;\r
-\r
- i++;\r
- if(i > respLen) {\r
- break;\r
- }\r
- }\r
- if(SSC_STATUS & (SSC_STATUS_RX_READY)) {\r
- volatile BYTE b = (BYTE)SSC_RECEIVE_HOLDING;\r
- (void)b;\r
- }\r
- }\r
- }\r
-}\r
-\r
-//=============================================================================\r
-// An ISO 14443 Type B reader. We take layer two commands, code them\r
-// appropriately, and then send them to the tag. We then listen for the\r
-// tag's response, which we leave in the buffer to be demodulated on the\r
-// PC side.\r
-//=============================================================================\r
-\r
-static struct {\r
- enum {\r
- DEMOD_UNSYNCD,\r
- DEMOD_PHASE_REF_TRAINING,\r
- DEMOD_AWAITING_FALLING_EDGE_OF_SOF,\r
- DEMOD_GOT_FALLING_EDGE_OF_SOF,\r
- DEMOD_AWAITING_START_BIT,\r
- DEMOD_RECEIVING_DATA,\r
- DEMOD_ERROR_WAIT\r
- } state;\r
- int bitCount;\r
- int posCount;\r
- int thisBit;\r
- int metric;\r
- int metricN;\r
- WORD shiftReg;\r
- BYTE *output;\r
- int len;\r
- int sumI;\r
- int sumQ;\r
-} Demod;\r
-\r
-/*\r
- * Handles reception of a bit from the tag\r
- *\r
- * LED handling:\r
- * LED C -> ON once we have received the SOF and are expecting the rest.\r
- * LED C -> OFF once we have received EOF or are unsynced\r
- *\r
- * Returns: true if we received a EOF\r
- * false if we are still waiting for some more\r
+//-----------------------------------------------------------------------------
+// Jonathan Westhues, split Nov 2006
+//
+// This code is licensed to you under the terms of the GNU GPL, version 2 or,
+// at your option, any later version. See the LICENSE.txt file for the text of
+// the license.
+//-----------------------------------------------------------------------------
+// Routines to support ISO 14443. This includes both the reader software and
+// the `fake tag' modes. At the moment only the Type B modulation is
+// supported.
+//-----------------------------------------------------------------------------
+
+#include "../include/proxmark3.h"
+#include "apps.h"
+#include "util.h"
+#include "string.h"
+
+#include "../common/iso14443crc.h"
+
+//static void GetSamplesFor14443(int weTx, int n);
+
+/*#define DEMOD_TRACE_SIZE 4096
+#define READER_TAG_BUFFER_SIZE 2048
+#define TAG_READER_BUFFER_SIZE 2048
+#define DEMOD_DMA_BUFFER_SIZE 1024
+*/
+//=============================================================================
+// 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
+// frame (i.e., a group of bytes between SOF and EOF), we check the CRC.
+// If it's good, then we can do something appropriate with it, and send
+// a response.
+//=============================================================================
+
+//-----------------------------------------------------------------------------
+// Code up a string of octets at layer 2 (including CRC, we don't generate
+// that here) so that they can be transmitted to the reader. Doesn't transmit
+// them yet, just leaves them ready to send in ToSend[].
+//-----------------------------------------------------------------------------
+static void CodeIso14443bAsTag(const uint8_t *cmd, int len)
+{
+ int i;
+
+ ToSendReset();
+
+ // Transmit a burst of ones, as the initial thing that lets the
+ // reader get phase sync. This (TR1) must be > 80/fs, per spec,
+ // but tag that I've tried (a Paypass) exceeds that by a fair bit,
+ // so I will too.
+ for(i = 0; i < 20; i++) {
+ ToSendStuffBit(1);
+ ToSendStuffBit(1);
+ ToSendStuffBit(1);
+ ToSendStuffBit(1);
+ }
+
+ // Send SOF.
+ for(i = 0; i < 10; i++) {
+ ToSendStuffBit(0);
+ ToSendStuffBit(0);
+ ToSendStuffBit(0);
+ ToSendStuffBit(0);
+ }
+ for(i = 0; i < 2; i++) {
+ ToSendStuffBit(1);
+ ToSendStuffBit(1);
+ ToSendStuffBit(1);
+ ToSendStuffBit(1);
+ }
+
+ for(i = 0; i < len; i++) {
+ int j;
+ uint8_t b = cmd[i];
+
+ // Start bit
+ ToSendStuffBit(0);
+ ToSendStuffBit(0);
+ ToSendStuffBit(0);
+ ToSendStuffBit(0);
+
+ // Data bits
+ for(j = 0; j < 8; j++) {
+ if(b & 1) {
+ ToSendStuffBit(1);
+ ToSendStuffBit(1);
+ ToSendStuffBit(1);
+ ToSendStuffBit(1);
+ } else {
+ ToSendStuffBit(0);
+ ToSendStuffBit(0);
+ ToSendStuffBit(0);
+ ToSendStuffBit(0);
+ }
+ b >>= 1;
+ }
+
+ // Stop bit
+ ToSendStuffBit(1);
+ ToSendStuffBit(1);
+ ToSendStuffBit(1);
+ ToSendStuffBit(1);
+ }
+
+ // Send SOF.
+ for(i = 0; i < 10; i++) {
+ ToSendStuffBit(0);
+ ToSendStuffBit(0);
+ ToSendStuffBit(0);
+ ToSendStuffBit(0);
+ }
+ for(i = 0; i < 10; i++) {
+ ToSendStuffBit(1);
+ ToSendStuffBit(1);
+ ToSendStuffBit(1);
+ ToSendStuffBit(1);
+ }
+
+ // Convert from last byte pos to length
+ ToSendMax++;
+
+ // Add a few more for slop
+ ToSendMax += 2;
+}
+
+//-----------------------------------------------------------------------------
+// The software UART that receives commands from the reader, and its state
+// variables.
+//-----------------------------------------------------------------------------
+static struct {
+ enum {
+ STATE_UNSYNCD,
+ STATE_GOT_FALLING_EDGE_OF_SOF,
+ STATE_AWAITING_START_BIT,
+ STATE_RECEIVING_DATA,
+ STATE_ERROR_WAIT
+ } state;
+ uint16_t shiftReg;
+ int bitCnt;
+ int byteCnt;
+ int byteCntMax;
+ int posCnt;
+ uint8_t *output;
+} Uart;
+
+/* Receive & handle a bit coming from the reader.