From: pwpiwi Date: Wed, 13 Nov 2019 15:42:29 +0000 (+0100) Subject: implement 'hf iclass snoop -j' X-Git-Url: http://cvs.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/commitdiff_plain/cd028159be9a6a3d7b158d2076cc94bf2b4f1143?ds=inline implement 'hf iclass snoop -j' * fix long option --jam * make room for one more bit for FPGA minor mode * new mode FPGA_HF_READER_MODE_SEND_JAM * implement jamming in Handle15693SampleFromReader --- diff --git a/armsrc/fpgaloader.c b/armsrc/fpgaloader.c index 5ca0cce1..8693d6b5 100644 --- a/armsrc/fpgaloader.c +++ b/armsrc/fpgaloader.c @@ -115,8 +115,7 @@ void SetupSpi(int mode) // Set up the synchronous serial port with the set of options that fits // the FPGA mode. Both RX and TX are always enabled. //----------------------------------------------------------------------------- -void FpgaSetupSsc(uint8_t FPGA_mode) -{ +void FpgaSetupSsc(uint16_t FPGA_mode) { // First configure the GPIOs, and get ourselves a clock. AT91C_BASE_PIOA->PIO_ASR = GPIO_SSC_FRAME | @@ -136,7 +135,7 @@ void FpgaSetupSsc(uint8_t FPGA_mode) // 8, 16 or 32 bits per transfer, no loopback, MSB first, 1 transfer per sync // pulse, no output sync - if ((FPGA_mode & 0xe0) == FPGA_MAJOR_MODE_HF_READER && FpgaGetCurrent() == FPGA_BITSTREAM_HF) { + if ((FPGA_mode & 0x1c0) == FPGA_MAJOR_MODE_HF_READER && FpgaGetCurrent() == FPGA_BITSTREAM_HF) { AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(16) | AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0); } else { AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) | AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0); @@ -450,10 +449,9 @@ void FpgaDownloadAndGo(int bitstream_version) // The bit format is: C3 C2 C1 C0 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0 // where C is the 4 bit command and D is the 12 bit data //----------------------------------------------------------------------------- -void FpgaSendCommand(uint16_t cmd, uint16_t v) -{ +void FpgaSendCommand(uint16_t cmd, uint16_t v) { SetupSpi(SPI_FPGA_MODE); - while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0); // wait for the transfer to complete + while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0); // wait for the transfer to complete AT91C_BASE_SPI->SPI_TDR = AT91C_SPI_LASTXFER | cmd | v; // send the data } @@ -462,21 +460,18 @@ void FpgaSendCommand(uint16_t cmd, uint16_t v) // vs. clone vs. etc.). This is now a special case of FpgaSendCommand() to // avoid changing this function's occurence everywhere in the source code. //----------------------------------------------------------------------------- -void FpgaWriteConfWord(uint16_t v) -{ +void FpgaWriteConfWord(uint16_t v) { FpgaSendCommand(FPGA_CMD_SET_CONFREG, v); } //----------------------------------------------------------------------------- // enable/disable FPGA internal tracing //----------------------------------------------------------------------------- -void FpgaEnableTracing(void) -{ +void FpgaEnableTracing(void) { FpgaSendCommand(FPGA_CMD_TRACE_ENABLE, 1); } -void FpgaDisableTracing(void) -{ +void FpgaDisableTracing(void) { FpgaSendCommand(FPGA_CMD_TRACE_ENABLE, 0); } diff --git a/armsrc/fpgaloader.h b/armsrc/fpgaloader.h index 42f9ccc6..09eaec42 100644 --- a/armsrc/fpgaloader.h +++ b/armsrc/fpgaloader.h @@ -19,7 +19,7 @@ void FpgaSendCommand(uint16_t cmd, uint16_t v); void FpgaWriteConfWord(uint16_t v); void FpgaDownloadAndGo(int bitstream_version); -void FpgaSetupSsc(uint8_t mode); +void FpgaSetupSsc(uint16_t mode); void SetupSpi(int mode); bool FpgaSetupSscDma(uint8_t *buf, uint16_t sample_count); void Fpga_print_status(); @@ -45,17 +45,17 @@ void SetAdcMuxFor(uint32_t whichGpio); // Definitions for the FPGA configuration word. // LF -#define FPGA_MAJOR_MODE_LF_ADC (0<<5) -#define FPGA_MAJOR_MODE_LF_EDGE_DETECT (1<<5) -#define FPGA_MAJOR_MODE_LF_PASSTHRU (2<<5) +#define FPGA_MAJOR_MODE_LF_ADC (0<<6) +#define FPGA_MAJOR_MODE_LF_EDGE_DETECT (1<<6) +#define FPGA_MAJOR_MODE_LF_PASSTHRU (2<<6) // HF -#define FPGA_MAJOR_MODE_HF_READER (0<<5) -#define FPGA_MAJOR_MODE_HF_SIMULATOR (1<<5) -#define FPGA_MAJOR_MODE_HF_ISO14443A (2<<5) -#define FPGA_MAJOR_MODE_HF_SNOOP (3<<5) -#define FPGA_MAJOR_MODE_HF_GET_TRACE (4<<5) +#define FPGA_MAJOR_MODE_HF_READER (0<<6) +#define FPGA_MAJOR_MODE_HF_SIMULATOR (1<<6) +#define FPGA_MAJOR_MODE_HF_ISO14443A (2<<6) +#define FPGA_MAJOR_MODE_HF_SNOOP (3<<6) +#define FPGA_MAJOR_MODE_HF_GET_TRACE (4<<6) // BOTH -#define FPGA_MAJOR_MODE_OFF (7<<5) +#define FPGA_MAJOR_MODE_OFF (7<<6) // Options for LF_ADC #define FPGA_LF_ADC_READER_FIELD (1<<0) @@ -74,10 +74,11 @@ void SetAdcMuxFor(uint32_t whichGpio); #define FPGA_HF_READER_MODE_SNOOP_IQ (5<<0) #define FPGA_HF_READER_MODE_SNOOP_AMPLITUDE (6<<0) #define FPGA_HF_READER_MODE_SNOOP_PHASE (7<<0) +#define FPGA_HF_READER_MODE_SEND_JAM (8<<0) -#define FPGA_HF_READER_SUBCARRIER_848_KHZ (0<<3) -#define FPGA_HF_READER_SUBCARRIER_424_KHZ (1<<3) -#define FPGA_HF_READER_SUBCARRIER_212_KHZ (2<<3) +#define FPGA_HF_READER_SUBCARRIER_848_KHZ (0<<4) +#define FPGA_HF_READER_SUBCARRIER_424_KHZ (1<<4) +#define FPGA_HF_READER_SUBCARRIER_212_KHZ (2<<4) // Options for the HF simulated tag, how to modulate #define FPGA_HF_SIMULATOR_NO_MODULATION (0<<0) diff --git a/armsrc/iso15693.c b/armsrc/iso15693.c index 9c50c036..f10b0206 100644 --- a/armsrc/iso15693.c +++ b/armsrc/iso15693.c @@ -84,7 +84,7 @@ static int DEBUG = 0; /////////////////////////////////////////////////////////////////////// // buffers -#define ISO15693_DMA_BUFFER_SIZE 128 // must be a power of 2 +#define ISO15693_DMA_BUFFER_SIZE 256 // must be a power of 2 #define ISO15693_MAX_RESPONSE_LENGTH 36 // allows read single block with the maximum block size of 256bits. Read multiple blocks not supported yet #define ISO15693_MAX_COMMAND_LENGTH 45 // allows write single block with the maximum block size of 256bits. Write multiple blocks not supported yet @@ -341,11 +341,6 @@ void TransmitTo15693Reader(const uint8_t *cmd, size_t len, uint32_t *start_time, } -static void jam(void) { - // send a short burst to jam the reader signal -} - - //============================================================================= // An ISO 15693 decoder for tag responses (one subcarrier only). // Uses cross correlation to identify each bit and EOF. @@ -392,7 +387,7 @@ typedef struct DecodeTag { } DecodeTag_t; -static int inline __attribute__((always_inline)) Handle15693SamplesFromTag(uint16_t amplitude, DecodeTag_t *restrict DecodeTag) { +static int inline __attribute__((always_inline)) Handle15693SamplesFromTag(uint16_t amplitude, DecodeTag_t *DecodeTag) { switch (DecodeTag->state) { case STATE_TAG_SOF_LOW: // waiting for a rising edge @@ -745,7 +740,8 @@ typedef struct DecodeReader { STATE_READER_AWAIT_2ND_RISING_EDGE_OF_SOF, STATE_READER_AWAIT_END_OF_SOF_1_OUT_OF_4, STATE_READER_RECEIVE_DATA_1_OUT_OF_4, - STATE_READER_RECEIVE_DATA_1_OUT_OF_256 + STATE_READER_RECEIVE_DATA_1_OUT_OF_256, + STATE_READER_RECEIVE_JAMMING } state; enum { CODING_1_OUT_OF_4, @@ -781,7 +777,7 @@ static void DecodeReaderReset(DecodeReader_t* DecodeReader) { } -static int inline __attribute__((always_inline)) Handle15693SampleFromReader(bool bit, DecodeReader_t *restrict DecodeReader) { +static int inline __attribute__((always_inline)) Handle15693SampleFromReader(bool bit, DecodeReader_t *DecodeReader) { switch (DecodeReader->state) { case STATE_READER_UNSYNCD: // wait for unmodulated carrier @@ -920,12 +916,6 @@ static int inline __attribute__((always_inline)) Handle15693SampleFromReader(boo } if (DecodeReader->bitCount == 15) { // we have a full byte DecodeReader->output[DecodeReader->byteCount++] = DecodeReader->shiftReg; - if (DecodeReader->byteCount == DecodeReader->jam_search_len) { - if (!memcmp(DecodeReader->output, DecodeReader->jam_search_string, DecodeReader->jam_search_len)) { - jam(); // send a jamming signal - Dbprintf("JAMMING!"); - } - } if (DecodeReader->byteCount > DecodeReader->byteCountMax) { // buffer overflow, give up LED_B_OFF(); @@ -933,6 +923,13 @@ static int inline __attribute__((always_inline)) Handle15693SampleFromReader(boo } DecodeReader->bitCount = 0; DecodeReader->shiftReg = 0; + if (DecodeReader->byteCount == DecodeReader->jam_search_len) { + if (!memcmp(DecodeReader->output, DecodeReader->jam_search_string, DecodeReader->jam_search_len)) { + LED_D_ON(); + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_MODE_SEND_JAM); + DecodeReader->state = STATE_READER_RECEIVE_JAMMING; + } + } } else { DecodeReader->bitCount++; } @@ -968,11 +965,42 @@ static int inline __attribute__((always_inline)) Handle15693SampleFromReader(boo LED_B_OFF(); DecodeReaderReset(DecodeReader); } + if (DecodeReader->byteCount == DecodeReader->jam_search_len) { + if (!memcmp(DecodeReader->output, DecodeReader->jam_search_string, DecodeReader->jam_search_len)) { + LED_D_ON(); + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_MODE_SEND_JAM); + DecodeReader->state = STATE_READER_RECEIVE_JAMMING; + } + } } DecodeReader->bitCount++; } break; + case STATE_READER_RECEIVE_JAMMING: + DecodeReader->posCount++; + if (DecodeReader->Coding == CODING_1_OUT_OF_4) { + if (DecodeReader->posCount == 7*16) { // 7 bits jammed + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_MODE_SNOOP_AMPLITUDE); // stop jamming + // FpgaDisableTracing(); + LED_D_OFF(); + } else if (DecodeReader->posCount == 8*16) { + DecodeReader->posCount = 0; + DecodeReader->output[DecodeReader->byteCount++] = 0x00; + DecodeReader->state = STATE_READER_RECEIVE_DATA_1_OUT_OF_4; + } + } else { + if (DecodeReader->posCount == 7*256) { // 7 bits jammend + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_MODE_SNOOP_AMPLITUDE); // stop jamming + LED_D_OFF(); + } else if (DecodeReader->posCount == 8*256) { + DecodeReader->posCount = 0; + DecodeReader->output[DecodeReader->byteCount++] = 0x00; + DecodeReader->state = STATE_READER_RECEIVE_DATA_1_OUT_OF_256; + } + } + break; + default: LED_B_OFF(); DecodeReaderReset(DecodeReader); @@ -1212,7 +1240,7 @@ void SnoopIso15693(uint8_t jam_search_len, uint8_t *jam_search_string) { if (upTo >= dmaBuf + ISO15693_DMA_BUFFER_SIZE) { // we have read all of the DMA buffer content. upTo = dmaBuf; // start reading the circular buffer from the beginning if (behindBy > (9*ISO15693_DMA_BUFFER_SIZE/10)) { - FpgaDisableTracing(); + // FpgaDisableTracing(); Dbprintf("About to blow circular buffer - aborted! behindBy=%d, samples=%d", behindBy, samples); break; } @@ -1305,8 +1333,6 @@ void SnoopIso15693(uint8_t jam_search_len, uint8_t *jam_search_string) { FpgaDisableSscDma(); - LEDsoff(); - DbpString("Snoop statistics:"); Dbprintf(" ExpectTagAnswer: %d, TagIsActive: %d, ReaderIsActive: %d", ExpectTagAnswer, TagIsActive, ReaderIsActive); Dbprintf(" DecodeTag State: %d", DecodeTag.state); diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 00493166..b59c0bdc 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -180,7 +180,7 @@ static int CmdHFiClassSnoop(const char *Cmd) { CLIParserInit("hf iclass snoop", "\nSnoop a communication between an iClass Reader and an iClass Tag.", NULL); void* argtable[] = { arg_param_begin, - arg_lit0("j", "--jam", "Jam (prevent) e-purse Updates"), + arg_lit0("j", "jam", "Jam (prevent) e-purse Updates"), arg_param_end }; if (CLIParserParseString(Cmd, argtable, arg_getsize(argtable), true)){ diff --git a/common/iso15693tools.c b/common/iso15693tools.c index 2da6c7f9..0769eefb 100644 --- a/common/iso15693tools.c +++ b/common/iso15693tools.c @@ -9,9 +9,8 @@ #include "iso15693tools.h" -#include "proxmark3.h" +#include #include -#include #ifdef ON_DEVICE #include "printf.h" #else @@ -90,7 +89,7 @@ uint16_t iclass_crc16(char *data_p, unsigned short length) { crc = ~crc; data = crc; crc = (crc << 8) | (data >> 8 & 0xff); - crc = crc ^ 0xBC3; + crc = crc ^ 0x0BC3; return (crc); } diff --git a/common/iso15693tools.h b/common/iso15693tools.h index a2eab293..b421c23f 100644 --- a/common/iso15693tools.h +++ b/common/iso15693tools.h @@ -4,9 +4,10 @@ #ifndef ISO15693TOOLS_H__ #define ISO15693TOOLS_H__ +#include + // ISO15693 CRC #define ISO15693_CRC_CHECK ((uint16_t)(~0xF0B8 & 0xFFFF)) // use this for checking of a correct crc - uint16_t Iso15693Crc(uint8_t *v, int n); int Iso15693AddCrc(uint8_t *req, int n); char* Iso15693sprintUID(char *target, uint8_t *uid); diff --git a/fpga/fpga_hf.bit b/fpga/fpga_hf.bit index 38990597..ea7c7ebf 100644 Binary files a/fpga/fpga_hf.bit and b/fpga/fpga_hf.bit differ diff --git a/fpga/fpga_hf.v b/fpga/fpga_hf.v index 01c6ebb2..4e1785d7 100644 --- a/fpga/fpga_hf.v +++ b/fpga/fpga_hf.v @@ -13,8 +13,14 @@ // iZsh , June 2014 //----------------------------------------------------------------------------- -// Defining modes and options. This must be aligned to the definitions in fpgaloader.h + +// Defining commands, modes and options. This must be aligned to the definitions in fpgaloader.h // Note: the definitions here are without shifts + +// Commands: +`define FPGA_CMD_SET_CONFREG 1 +`define FPGA_CMD_TRACE_ENABLE 2 + // Major modes: `define FPGA_MAJOR_MODE_LF_ADC 0 `define FPGA_MAJOR_MODE_LF_EDGE_DETECT 1 @@ -35,6 +41,7 @@ `define FPGA_HF_READER_MODE_SNIFF_IQ 5 `define FPGA_HF_READER_MODE_SNIFF_AMPLITUDE 6 `define FPGA_HF_READER_MODE_SNIFF_PHASE 7 +`define FPGA_HF_READER_MODE_SEND_JAM 8 `define FPGA_HF_READER_SUBCARRIER_848_KHZ 0 `define FPGA_HF_READER_SUBCARRIER_424_KHZ 1 `define FPGA_HF_READER_SUBCARRIER_212_KHZ 2 @@ -79,7 +86,7 @@ module fpga_hf( //----------------------------------------------------------------------------- reg [15:0] shift_reg; -reg [7:0] conf_word; +reg [8:0] conf_word; reg trace_enable; // We switch modes between transmitting to the 13.56 MHz tag and receiving @@ -88,8 +95,8 @@ reg trace_enable; always @(posedge ncs) begin case(shift_reg[15:12]) - 4'b0001: conf_word <= shift_reg[7:0]; // FPGA_CMD_SET_CONFREG - 4'b0010: trace_enable <= shift_reg[0]; // FPGA_CMD_TRACE_ENABLE + `FPGA_CMD_SET_CONFREG: conf_word <= shift_reg[8:0]; + `FPGA_CMD_TRACE_ENABLE: trace_enable <= shift_reg[0]; endcase end @@ -103,11 +110,11 @@ begin end // select module (outputs) based on major mode -wire [2:0] major_mode = conf_word[7:5]; +wire [2:0] major_mode = conf_word[8:6]; // configuring the HF reader -wire [1:0] subcarrier_frequency = conf_word[4:3]; -wire [2:0] minor_mode = conf_word[2:0]; +wire [1:0] subcarrier_frequency = conf_word[5:4]; +wire [3:0] minor_mode = conf_word[3:0]; //----------------------------------------------------------------------------- // And then we instantiate the modules corresponding to each of the FPGA's diff --git a/fpga/fpga_lf.bit b/fpga/fpga_lf.bit index bd4d821b..96d27372 100644 Binary files a/fpga/fpga_lf.bit and b/fpga/fpga_lf.bit differ diff --git a/fpga/fpga_lf.v b/fpga/fpga_lf.v index 1b7a1127..bb0795e8 100644 --- a/fpga/fpga_lf.v +++ b/fpga/fpga_lf.v @@ -29,17 +29,18 @@ module fpga_lf( reg [15:0] shift_reg; reg [7:0] divisor; -reg [7:0] conf_word; +reg [8:0] conf_word; reg [7:0] user_byte1; always @(posedge ncs) begin - case(shift_reg[15:12]) - 4'b0001: + case (shift_reg[15:12]) + 4'b0001: // FPGA_CMD_SET_CONFREG begin - conf_word <= shift_reg[7:0]; - if (shift_reg[7:0] == 8'b00000001) begin // LF edge detect - user_byte1 <= 127; // default threshold + conf_word <= shift_reg[8:0]; + if (shift_reg[8:0] == 9'b000000001) + begin // LF edge detect + user_byte1 <= 127; // default threshold end end 4'b0010: divisor <= shift_reg[7:0]; // FPGA_CMD_SET_DIVISOR @@ -49,14 +50,14 @@ end always @(posedge spck) begin - if(~ncs) + if (~ncs) begin shift_reg[15:1] <= shift_reg[14:0]; shift_reg[0] <= mosi; end end -wire [2:0] major_mode = conf_word[7:5]; +wire [2:0] major_mode = conf_word[8:6]; // For the low-frequency configuration: wire lf_field = conf_word[0]; diff --git a/fpga/hi_iso14443a.v b/fpga/hi_iso14443a.v index e460a2cc..1c6e4cbf 100644 --- a/fpga/hi_iso14443a.v +++ b/fpga/hi_iso14443a.v @@ -18,7 +18,7 @@ module hi_iso14443a( input ssp_dout; output ssp_frame, ssp_din, ssp_clk; output dbg; - input [2:0] mod_type; + input [3:0] mod_type; wire adc_clk = ck_1356meg; diff --git a/fpga/hi_reader.v b/fpga/hi_reader.v index 65f1fd35..fe5ae4e5 100644 --- a/fpga/hi_reader.v +++ b/fpga/hi_reader.v @@ -19,7 +19,7 @@ module hi_reader( output ssp_frame, ssp_din, ssp_clk; output dbg; input [1:0] subcarrier_frequency; - input [2:0] minor_mode; + input [3:0] minor_mode; assign adc_clk = ck_1356meg; // sample frequency is 13,56 MHz @@ -257,6 +257,19 @@ end assign ssp_din = corr_i_out[7]; +// a jamming signal +reg jam_signal; +reg [3:0] jam_counter; + +always @(negedge adc_clk) +begin + if (corr_i_cnt == 6'd0) + begin + jam_counter <= jam_counter + 1; + jam_signal <= jam_counter[1] ^ jam_counter[3]; + end +end + // Antenna drivers reg pwr_hi, pwr_oe4; @@ -272,10 +285,15 @@ begin pwr_hi = ck_1356meg & ~ssp_dout; pwr_oe4 = 1'b0; end + else if (minor_mode == `FPGA_HF_READER_MODE_SEND_JAM) + begin + pwr_hi = ck_1356meg & jam_signal; + pwr_oe4 = 1'b0; + end else if (minor_mode == `FPGA_HF_READER_MODE_SNIFF_IQ || minor_mode == `FPGA_HF_READER_MODE_SNIFF_AMPLITUDE || minor_mode == `FPGA_HF_READER_MODE_SNIFF_PHASE) - begin + begin // all off pwr_hi = 1'b0; pwr_oe4 = 1'b0; end @@ -284,7 +302,7 @@ begin pwr_hi = ck_1356meg; pwr_oe4 = 1'b0; end -end +end // always on assign pwr_oe1 = 1'b0; diff --git a/fpga/hi_simulate.v b/fpga/hi_simulate.v index 5fc2e113..7627e932 100644 --- a/fpga/hi_simulate.v +++ b/fpga/hi_simulate.v @@ -31,7 +31,7 @@ module hi_simulate( input ssp_dout; output ssp_frame, ssp_din, ssp_clk; output dbg; - input [2:0] mod_type; + input [3:0] mod_type; assign adc_clk = ck_1356meg;