From: pwpiwi Date: Fri, 8 Nov 2019 13:27:09 +0000 (+0100) Subject: fix 'hf iclass snoop' X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/commitdiff_plain/be09ea86035044f67e0419b067ac54ee055ad9ee?ds=inline;hp=-c fix 'hf iclass snoop' * code deduplication: use ISO15693 snoop function * speed up SnoopIso15693(), reduce DMA buffer size * add jamming option '-j' to 'hf iclass snoop' * fix issue #882 * whitespace fixes --- be09ea86035044f67e0419b067ac54ee055ad9ee diff --git a/armsrc/Makefile b/armsrc/Makefile index 7348fda6..3d1ba79e 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -21,12 +21,12 @@ else SRC_LCD = endif SRC_LF = lfops.c hitag2.c hitagS.c lfsampling.c pcf7931.c lfdemod.c protocols.c -SRC_ISO15693 = iso15693.c iso15693tools.c +SRC_ISO15693 = iso15693.c SRC_ISO14443a = epa.c iso14443a.c mifareutil.c mifarecmd.c mifaresniff.c mifaresim.c SRC_ISO14443b = iso14443b.c SRC_CRAPTO1 = crypto1.c SRC_DES = platform_util_arm.c des.c -SRC_CRC = iso14443crc.c crc.c crc16.c crc32.c parity.c +SRC_CRC = iso14443crc.c crc.c crc16.c crc32.c parity.c iso15693tools.c SRC_SMARTCARD = i2c.c #the FPGA bitstream files. Note: order matters! @@ -43,7 +43,6 @@ APP_CFLAGS += -I../zlib # Compile these in thumb mode (small size) THUMBSRC = start.c \ $(SRC_LCD) \ - $(SRC_ISO15693) \ $(SRC_LF) \ $(SRC_ZLIB) \ $(SRC_SMARTCARD) \ @@ -54,6 +53,9 @@ THUMBSRC = start.c \ usb_cdc.c \ cmd.c +# Compile these in thumb mode optimized for speed (still smaller than ARM mode) +THUMBOPTSRC = $(SRC_ISO15693) + # These are to be compiled in ARM mode ARMSRC = fpgaloader.c \ legicrf.c \ @@ -72,7 +74,7 @@ ARMSRC = fpgaloader.c \ VERSIONSRC = version.c \ fpga_version_info.c -# Do not move this inclusion before the definition of {THUMB,ASM,ARM}SRC +# Do not move this inclusion before the definition of {THUMB,THUMBOPT,ASM,ARM}SRC include ../common/Makefile.common OBJS = $(OBJDIR)/fullimage.s19 @@ -99,7 +101,7 @@ $(OBJDIR)/fpga_all.bit.z: $(FPGA_BITSTREAMS) $(FPGA_COMPRESSOR) $(FPGA_COMPRESSOR): make -C ../client $(notdir $(FPGA_COMPRESSOR)) -$(OBJDIR)/fullimage.stage1.elf: $(VERSIONOBJ) $(OBJDIR)/fpga_all.o $(THUMBOBJ) $(ARMOBJ) +$(OBJDIR)/fullimage.stage1.elf: $(VERSIONOBJ) $(OBJDIR)/fpga_all.o $(THUMBOBJ) $(THUMBOPTOBJ) $(ARMOBJ) $(CC) $(LDFLAGS) -Wl,-T,ldscript,-Map,$(patsubst %.elf,%.map,$@) -o $@ $^ $(LIBS) $(OBJDIR)/fullimage.nodata.bin: $(OBJDIR)/fullimage.stage1.elf diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 56da5434..589f394d 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1142,7 +1142,7 @@ void UsbPacketReceived(uint8_t *packet, int len) break; case CMD_SNOOP_ISO_15693: - SnoopIso15693(); + SnoopIso15693(0, NULL); break; case CMD_ISO_15693_COMMAND: @@ -1307,7 +1307,7 @@ void UsbPacketReceived(uint8_t *packet, int len) #ifdef WITH_ICLASS // Makes use of ISO14443a FPGA Firmware case CMD_SNOOP_ICLASS: - SnoopIClass(); + SnoopIClass(c->arg[0], c->d.asBytes); break; case CMD_SIMULATE_TAG_ICLASS: SimulateIClass(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); diff --git a/armsrc/iclass.c b/armsrc/iclass.c index 430597c1..6a2fd648 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -69,693 +69,18 @@ #define ICLASS_READER_TIMEOUT_UPDATE 3390 // 16000us, nominal 4-15ms #define ICLASS_READER_TIMEOUT_OTHERS 80 // 380us, nominal 330us +#define ICLASS_BUFFER_SIZE 34 // we expect max 34 bytes as tag answer (response to READ4) -//----------------------------------------------------------------------------- -// The software UART that receives commands from the reader, and its state -// variables. -//----------------------------------------------------------------------------- -static struct { - enum { - STATE_UNSYNCD, - STATE_START_OF_COMMUNICATION, - STATE_RECEIVING - } state; - uint16_t shiftReg; - int bitCnt; - int byteCnt; - int byteCntMax; - int posCnt; - int nOutOfCnt; - int OutOfCnt; - int syncBit; - int samples; - int highCnt; - int swapper; - int counter; - int bitBuffer; - int dropPosition; - uint8_t *output; -} Uart; - -static RAMFUNC int OutOfNDecoding(int bit) { - //int error = 0; - int bitright; - - if (!Uart.bitBuffer) { - Uart.bitBuffer = bit ^ 0xFF0; - return false; - } else { - Uart.bitBuffer <<= 4; - Uart.bitBuffer ^= bit; - } - - /*if (Uart.swapper) { - Uart.output[Uart.byteCnt] = Uart.bitBuffer & 0xFF; - Uart.byteCnt++; - Uart.swapper = 0; - if (Uart.byteCnt > 15) { return true; } - } - else { - Uart.swapper = 1; - }*/ - - if (Uart.state != STATE_UNSYNCD) { - Uart.posCnt++; - - if ((Uart.bitBuffer & Uart.syncBit) ^ Uart.syncBit) { - bit = 0x00; - } else { - bit = 0x01; - } - if (((Uart.bitBuffer << 1) & Uart.syncBit) ^ Uart.syncBit) { - bitright = 0x00; - } else { - bitright = 0x01; - } - if (bit != bitright) { - bit = bitright; - } - - - // So, now we only have to deal with *bit*, lets see... - if (Uart.posCnt == 1) { - // measurement first half bitperiod - if (!bit) { - // Drop in first half means that we are either seeing - // an SOF or an EOF. - - if (Uart.nOutOfCnt == 1) { - // End of Communication - Uart.state = STATE_UNSYNCD; - Uart.highCnt = 0; - if (Uart.byteCnt == 0) { - // Its not straightforward to show single EOFs - // So just leave it and do not return true - Uart.output[0] = 0xf0; - Uart.byteCnt++; - } else { - return true; - } - } else if (Uart.state != STATE_START_OF_COMMUNICATION) { - // When not part of SOF or EOF, it is an error - Uart.state = STATE_UNSYNCD; - Uart.highCnt = 0; - //error = 4; - } - } - } else { - // measurement second half bitperiod - // Count the bitslot we are in... (ISO 15693) - Uart.nOutOfCnt++; - - if (!bit) { - if (Uart.dropPosition) { - if (Uart.state == STATE_START_OF_COMMUNICATION) { - //error = 1; - } else { - //error = 7; - } - // It is an error if we already have seen a drop in current frame - Uart.state = STATE_UNSYNCD; - Uart.highCnt = 0; - } else { - Uart.dropPosition = Uart.nOutOfCnt; - } - } - - Uart.posCnt = 0; - - - if (Uart.nOutOfCnt == Uart.OutOfCnt && Uart.OutOfCnt == 4) { - Uart.nOutOfCnt = 0; - - if (Uart.state == STATE_START_OF_COMMUNICATION) { - if (Uart.dropPosition == 4) { - Uart.state = STATE_RECEIVING; - Uart.OutOfCnt = 256; - } else if (Uart.dropPosition == 3) { - Uart.state = STATE_RECEIVING; - Uart.OutOfCnt = 4; - //Uart.output[Uart.byteCnt] = 0xdd; - //Uart.byteCnt++; - } else { - Uart.state = STATE_UNSYNCD; - Uart.highCnt = 0; - } - Uart.dropPosition = 0; - } else { - // RECEIVING DATA - // 1 out of 4 - if (!Uart.dropPosition) { - Uart.state = STATE_UNSYNCD; - Uart.highCnt = 0; - //error = 9; - } else { - Uart.shiftReg >>= 2; - - // Swap bit order - Uart.dropPosition--; - //if (Uart.dropPosition == 1) { Uart.dropPosition = 2; } - //else if (Uart.dropPosition == 2) { Uart.dropPosition = 1; } - - Uart.shiftReg ^= ((Uart.dropPosition & 0x03) << 6); - Uart.bitCnt += 2; - Uart.dropPosition = 0; - - if (Uart.bitCnt == 8) { - Uart.output[Uart.byteCnt] = (Uart.shiftReg & 0xff); - Uart.byteCnt++; - Uart.bitCnt = 0; - Uart.shiftReg = 0; - } - } - } - } else if (Uart.nOutOfCnt == Uart.OutOfCnt) { - // RECEIVING DATA - // 1 out of 256 - if (!Uart.dropPosition) { - Uart.state = STATE_UNSYNCD; - Uart.highCnt = 0; - //error = 3; - } else { - Uart.dropPosition--; - Uart.output[Uart.byteCnt] = (Uart.dropPosition & 0xff); - Uart.byteCnt++; - Uart.bitCnt = 0; - Uart.shiftReg = 0; - Uart.nOutOfCnt = 0; - Uart.dropPosition = 0; - } - } - - /*if (error) { - Uart.output[Uart.byteCnt] = 0xAA; - Uart.byteCnt++; - Uart.output[Uart.byteCnt] = error & 0xFF; - Uart.byteCnt++; - Uart.output[Uart.byteCnt] = 0xAA; - Uart.byteCnt++; - Uart.output[Uart.byteCnt] = (Uart.bitBuffer >> 8) & 0xFF; - Uart.byteCnt++; - Uart.output[Uart.byteCnt] = Uart.bitBuffer & 0xFF; - Uart.byteCnt++; - Uart.output[Uart.byteCnt] = (Uart.syncBit >> 3) & 0xFF; - Uart.byteCnt++; - Uart.output[Uart.byteCnt] = 0xAA; - Uart.byteCnt++; - return true; - }*/ - } - - } else { - bit = Uart.bitBuffer & 0xf0; - bit >>= 4; - bit ^= 0x0F; // drops become 1s ;-) - if (bit) { - // should have been high or at least (4 * 128) / fc - // according to ISO this should be at least (9 * 128 + 20) / fc - if (Uart.highCnt == 8) { - // we went low, so this could be start of communication - // it turns out to be safer to choose a less significant - // syncbit... so we check whether the neighbour also represents the drop - Uart.posCnt = 1; // apparently we are busy with our first half bit period - Uart.syncBit = bit & 8; - Uart.samples = 3; - if (!Uart.syncBit) { Uart.syncBit = bit & 4; Uart.samples = 2; } - else if (bit & 4) { Uart.syncBit = bit & 4; Uart.samples = 2; bit <<= 2; } - if (!Uart.syncBit) { Uart.syncBit = bit & 2; Uart.samples = 1; } - else if (bit & 2) { Uart.syncBit = bit & 2; Uart.samples = 1; bit <<= 1; } - if (!Uart.syncBit) { Uart.syncBit = bit & 1; Uart.samples = 0; - if (Uart.syncBit && (Uart.bitBuffer & 8)) { - Uart.syncBit = 8; - - // the first half bit period is expected in next sample - Uart.posCnt = 0; - Uart.samples = 3; - } - } else if (bit & 1) { Uart.syncBit = bit & 1; Uart.samples = 0; } - - Uart.syncBit <<= 4; - Uart.state = STATE_START_OF_COMMUNICATION; - Uart.bitCnt = 0; - Uart.byteCnt = 0; - Uart.nOutOfCnt = 0; - Uart.OutOfCnt = 4; // Start at 1/4, could switch to 1/256 - Uart.dropPosition = 0; - Uart.shiftReg = 0; - //error = 0; - } else { - Uart.highCnt = 0; - } - } else if (Uart.highCnt < 8) { - Uart.highCnt++; - } - } - - return false; -} - - -//============================================================================= -// Manchester -//============================================================================= - -static struct { - enum { - DEMOD_UNSYNCD, - DEMOD_START_OF_COMMUNICATION, - DEMOD_START_OF_COMMUNICATION2, - DEMOD_START_OF_COMMUNICATION3, - DEMOD_SOF_COMPLETE, - DEMOD_MANCHESTER_D, - DEMOD_MANCHESTER_E, - DEMOD_END_OF_COMMUNICATION, - DEMOD_END_OF_COMMUNICATION2, - DEMOD_MANCHESTER_F, - DEMOD_ERROR_WAIT - } state; - int bitCount; - int posCount; - int syncBit; - uint16_t shiftReg; - int buffer; - int buffer2; - int buffer3; - int buff; - int samples; - int len; - enum { - SUB_NONE, - SUB_FIRST_HALF, - SUB_SECOND_HALF, - SUB_BOTH - } sub; - uint8_t *output; -} Demod; - -static RAMFUNC int ManchesterDecoding(int v) { - int bit; - int modulation; - int error = 0; - - bit = Demod.buffer; - Demod.buffer = Demod.buffer2; - Demod.buffer2 = Demod.buffer3; - Demod.buffer3 = v; - - if (Demod.buff < 3) { - Demod.buff++; - return false; - } - - if (Demod.state==DEMOD_UNSYNCD) { - Demod.output[Demod.len] = 0xfa; - Demod.syncBit = 0; - //Demod.samples = 0; - Demod.posCount = 1; // This is the first half bit period, so after syncing handle the second part - - if (bit & 0x08) { - Demod.syncBit = 0x08; - } - - if (bit & 0x04) { - if (Demod.syncBit) { - bit <<= 4; - } - Demod.syncBit = 0x04; - } - - if (bit & 0x02) { - if (Demod.syncBit) { - bit <<= 2; - } - Demod.syncBit = 0x02; - } - - if (bit & 0x01 && Demod.syncBit) { - Demod.syncBit = 0x01; - } - - if (Demod.syncBit) { - Demod.len = 0; - Demod.state = DEMOD_START_OF_COMMUNICATION; - Demod.sub = SUB_FIRST_HALF; - Demod.bitCount = 0; - Demod.shiftReg = 0; - Demod.samples = 0; - if (Demod.posCount) { - switch (Demod.syncBit) { - case 0x08: Demod.samples = 3; break; - case 0x04: Demod.samples = 2; break; - case 0x02: Demod.samples = 1; break; - case 0x01: Demod.samples = 0; break; - } - // SOF must be long burst... otherwise stay unsynced!!! - if (!(Demod.buffer & Demod.syncBit) || !(Demod.buffer2 & Demod.syncBit)) { - Demod.state = DEMOD_UNSYNCD; - } - } else { - // SOF must be long burst... otherwise stay unsynced!!! - if (!(Demod.buffer2 & Demod.syncBit) || !(Demod.buffer3 & Demod.syncBit)) { - Demod.state = DEMOD_UNSYNCD; - error = 0x88; - } - - } - error = 0; - - } - } else { - // state is DEMOD is in SYNC from here on. - modulation = bit & Demod.syncBit; - modulation |= ((bit << 1) ^ ((Demod.buffer & 0x08) >> 3)) & Demod.syncBit; - - Demod.samples += 4; - - if (Demod.posCount == 0) { - Demod.posCount = 1; - if (modulation) { - Demod.sub = SUB_FIRST_HALF; - } else { - Demod.sub = SUB_NONE; - } - } else { - Demod.posCount = 0; - if (modulation) { - if (Demod.sub == SUB_FIRST_HALF) { - Demod.sub = SUB_BOTH; - } else { - Demod.sub = SUB_SECOND_HALF; - } - } else if (Demod.sub == SUB_NONE) { - if (Demod.state == DEMOD_SOF_COMPLETE) { - Demod.output[Demod.len] = 0x0f; - Demod.len++; - Demod.state = DEMOD_UNSYNCD; - return true; - } else { - Demod.state = DEMOD_ERROR_WAIT; - error = 0x33; - } - } - - switch(Demod.state) { - case DEMOD_START_OF_COMMUNICATION: - if (Demod.sub == SUB_BOTH) { - Demod.state = DEMOD_START_OF_COMMUNICATION2; - Demod.posCount = 1; - Demod.sub = SUB_NONE; - } else { - Demod.output[Demod.len] = 0xab; - Demod.state = DEMOD_ERROR_WAIT; - error = 0xd2; - } - break; - case DEMOD_START_OF_COMMUNICATION2: - if (Demod.sub == SUB_SECOND_HALF) { - Demod.state = DEMOD_START_OF_COMMUNICATION3; - } else { - Demod.output[Demod.len] = 0xab; - Demod.state = DEMOD_ERROR_WAIT; - error = 0xd3; - } - break; - case DEMOD_START_OF_COMMUNICATION3: - if (Demod.sub == SUB_SECOND_HALF) { - Demod.state = DEMOD_SOF_COMPLETE; - } else { - Demod.output[Demod.len] = 0xab; - Demod.state = DEMOD_ERROR_WAIT; - error = 0xd4; - } - break; - case DEMOD_SOF_COMPLETE: - case DEMOD_MANCHESTER_D: - case DEMOD_MANCHESTER_E: - // OPPOSITE FROM ISO14443 - 11110000 = 0 (1 in 14443) - // 00001111 = 1 (0 in 14443) - if (Demod.sub == SUB_SECOND_HALF) { // SUB_FIRST_HALF - Demod.bitCount++; - Demod.shiftReg = (Demod.shiftReg >> 1) ^ 0x100; - Demod.state = DEMOD_MANCHESTER_D; - } else if (Demod.sub == SUB_FIRST_HALF) { // SUB_SECOND_HALF - Demod.bitCount++; - Demod.shiftReg >>= 1; - Demod.state = DEMOD_MANCHESTER_E; - } else if (Demod.sub == SUB_BOTH) { - Demod.state = DEMOD_MANCHESTER_F; - } else { - Demod.state = DEMOD_ERROR_WAIT; - error = 0x55; - } - break; - - case DEMOD_MANCHESTER_F: - // Tag response does not need to be a complete byte! - if (Demod.len > 0 || Demod.bitCount > 0) { - if (Demod.bitCount > 1) { // was > 0, do not interpret last closing bit, is part of EOF - Demod.shiftReg >>= (9 - Demod.bitCount); // right align data - Demod.output[Demod.len] = Demod.shiftReg & 0xff; - Demod.len++; - } - - Demod.state = DEMOD_UNSYNCD; - return true; - } else { - Demod.output[Demod.len] = 0xad; - Demod.state = DEMOD_ERROR_WAIT; - error = 0x03; - } - break; - - case DEMOD_ERROR_WAIT: - Demod.state = DEMOD_UNSYNCD; - break; - - default: - Demod.output[Demod.len] = 0xdd; - Demod.state = DEMOD_UNSYNCD; - break; - } - - if (Demod.bitCount >= 8) { - Demod.shiftReg >>= 1; - Demod.output[Demod.len] = (Demod.shiftReg & 0xff); - Demod.len++; - Demod.bitCount = 0; - Demod.shiftReg = 0; - } - - if (error) { - Demod.output[Demod.len] = 0xBB; - Demod.len++; - Demod.output[Demod.len] = error & 0xFF; - Demod.len++; - Demod.output[Demod.len] = 0xBB; - Demod.len++; - Demod.output[Demod.len] = bit & 0xFF; - Demod.len++; - Demod.output[Demod.len] = Demod.buffer & 0xFF; - Demod.len++; - // Look harder ;-) - Demod.output[Demod.len] = Demod.buffer2 & 0xFF; - Demod.len++; - Demod.output[Demod.len] = Demod.syncBit & 0xFF; - Demod.len++; - Demod.output[Demod.len] = 0xBB; - Demod.len++; - return true; - } - - } - - } // end (state != UNSYNCED) - - return false; -} //============================================================================= -// Finally, a `sniffer' for iClass communication +// A `sniffer' for iClass communication // Both sides of communication! //============================================================================= - -//----------------------------------------------------------------------------- -// Record the sequence of commands sent by the reader to the tag, with -// triggering so that we start recording at the point that the tag is moved -// near the reader. -//----------------------------------------------------------------------------- -void RAMFUNC SnoopIClass(void) { - - // We won't start recording the frames that we acquire until we trigger; - // a good trigger condition to get started is probably when we see a - // response from the tag. - //int triggered = false; // false to wait first for card - - // The command (reader -> tag) that we're receiving. - // The length of a received command will in most cases be no more than 18 bytes. - // So 32 should be enough! - #define ICLASS_BUFFER_SIZE 32 - uint8_t readerToTagCmd[ICLASS_BUFFER_SIZE]; - // The response (tag -> reader) that we're receiving. - uint8_t tagToReaderResponse[ICLASS_BUFFER_SIZE]; - - FpgaDownloadAndGo(FPGA_BITSTREAM_HF); - - // free all BigBuf memory - BigBuf_free(); - // The DMA buffer, used to stream samples from the FPGA - uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE); - - set_tracing(true); - clear_trace(); - iso14a_set_trigger(false); - - int lastRxCounter; - uint8_t *upTo; - int smpl; - int maxBehindBy = 0; - - // Count of samples received so far, so that we can include timing - // information in the trace buffer. - int samples = 0; - rsamples = 0; - - // Set up the demodulator for tag -> reader responses. - Demod.output = tagToReaderResponse; - Demod.len = 0; - Demod.state = DEMOD_UNSYNCD; - - // Setup for the DMA. - FpgaSetupSsc(FPGA_MAJOR_MODE_HF_ISO14443A); - upTo = dmaBuf; - lastRxCounter = DMA_BUFFER_SIZE; - FpgaSetupSscDma((uint8_t *)dmaBuf, DMA_BUFFER_SIZE); - - // And the reader -> tag commands - memset(&Uart, 0, sizeof(Uart)); - Uart.output = readerToTagCmd; - Uart.byteCntMax = 32; // was 100 (greg)//////////////////////////////////////////////////////////////////////// - Uart.state = STATE_UNSYNCD; - - // And put the FPGA in the appropriate mode - // Signal field is off with the appropriate LED - LED_D_OFF(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_SNIFFER); - SetAdcMuxFor(GPIO_MUXSEL_HIPKD); - - uint32_t time_0 = GetCountSspClk(); - uint32_t time_start = 0; - uint32_t time_stop = 0; - - int div = 0; - //int div2 = 0; - int decbyte = 0; - int decbyter = 0; - - // And now we loop, receiving samples. - for (;;) { - LED_A_ON(); - WDT_HIT(); - int behindBy = (lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR) & (DMA_BUFFER_SIZE-1); - if (behindBy > maxBehindBy) { - maxBehindBy = behindBy; - if (behindBy > (9 * DMA_BUFFER_SIZE / 10)) { - Dbprintf("blew circular buffer! behindBy=0x%x", behindBy); - goto done; - } - } - if (behindBy < 1) continue; - - LED_A_OFF(); - smpl = upTo[0]; - upTo++; - lastRxCounter -= 1; - if (upTo - dmaBuf > DMA_BUFFER_SIZE) { - upTo -= DMA_BUFFER_SIZE; - lastRxCounter += DMA_BUFFER_SIZE; - AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) upTo; - AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE; - } - - //samples += 4; - samples += 1; - - if (smpl & 0xF) { - decbyte ^= (1 << (3 - div)); - } - - // FOR READER SIDE COMMUMICATION... - - decbyter <<= 2; - decbyter ^= (smpl & 0x30); - - div++; - - if ((div + 1) % 2 == 0) { - smpl = decbyter; - if (OutOfNDecoding((smpl & 0xF0) >> 4)) { - rsamples = samples - Uart.samples; - time_stop = (GetCountSspClk()-time_0) << 4; - - //if (!LogTrace(Uart.output, Uart.byteCnt, rsamples, Uart.parityBits,true)) break; - //if (!LogTrace(NULL, 0, Uart.endTime*16 - DELAY_READER_AIR2ARM_AS_SNIFFER, 0, true)) break; - uint8_t parity[MAX_PARITY_SIZE]; - GetParity(Uart.output, Uart.byteCnt, parity); - LogTrace_ISO15693(Uart.output, Uart.byteCnt, time_start*32, time_stop*32, parity, true); - - /* And ready to receive another command. */ - Uart.state = STATE_UNSYNCD; - /* And also reset the demod code, which might have been */ - /* false-triggered by the commands from the reader. */ - Demod.state = DEMOD_UNSYNCD; - Uart.byteCnt = 0; - } else { - time_start = (GetCountSspClk()-time_0) << 4; - } - decbyter = 0; - } - - if (div > 3) { - smpl = decbyte; - if (ManchesterDecoding(smpl & 0x0F)) { - time_stop = (GetCountSspClk()-time_0) << 4; - - rsamples = samples - Demod.samples; - - uint8_t parity[MAX_PARITY_SIZE]; - GetParity(Demod.output, Demod.len, parity); - LogTrace_ISO15693(Demod.output, Demod.len, time_start*32, time_stop*32, parity, false); - - // And ready to receive another response. - memset(&Demod, 0, sizeof(Demod)); - Demod.output = tagToReaderResponse; - Demod.state = DEMOD_UNSYNCD; - } else { - time_start = (GetCountSspClk()-time_0) << 4; - } - - div = 0; - decbyte = 0x00; - } - - if (BUTTON_PRESS()) { - DbpString("cancelled_a"); - goto done; - } - } - - DbpString("COMMAND FINISHED"); - - Dbprintf("%x %x %x", maxBehindBy, Uart.state, Uart.byteCnt); - Dbprintf("%x %x %x", Uart.byteCntMax, BigBuf_get_traceLen(), (int)Uart.output[0]); - -done: - AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS; - Dbprintf("%x %x %x", maxBehindBy, Uart.state, Uart.byteCnt); - Dbprintf("%x %x %x", Uart.byteCntMax, BigBuf_get_traceLen(), (int)Uart.output[0]); - LEDsoff(); +void SnoopIClass(uint8_t jam_search_len, uint8_t *jam_search_string) { + SnoopIso15693(jam_search_len, jam_search_string); } + void rotateCSN(uint8_t* originalCSN, uint8_t* rotatedCSN) { int i; for (i = 0; i < 8; i++) { @@ -763,6 +88,7 @@ void rotateCSN(uint8_t* originalCSN, uint8_t* rotatedCSN) { } } + // Encode SOF only static void CodeIClassTagSOF() { ToSendReset(); @@ -770,6 +96,7 @@ static void CodeIClassTagSOF() { ToSendMax++; } + static void AppendCrc(uint8_t *data, int len) { ComputeCrc14443(CRC_ICLASS, data, len, data+len, data+len+1); } diff --git a/armsrc/iclass.h b/armsrc/iclass.h index 9666e888..541e1a2c 100644 --- a/armsrc/iclass.h +++ b/armsrc/iclass.h @@ -16,9 +16,8 @@ #include #include -#include "common.h" // for RAMFUNC -extern void RAMFUNC SnoopIClass(void); +extern void SnoopIClass(uint8_t jam_search_len, uint8_t *jam_search_string); extern void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain); extern void ReaderIClass(uint8_t arg0); extern void ReaderIClass_Replay(uint8_t arg0, uint8_t *MAC); diff --git a/armsrc/iso15693.c b/armsrc/iso15693.c index 761340e9..9c50c036 100644 --- a/armsrc/iso15693.c +++ b/armsrc/iso15693.c @@ -78,25 +78,26 @@ static int DEBUG = 0; -// specific LogTrace function for ISO15693: the duration needs to be scaled because otherwise it won't fit into a uint16_t -bool LogTrace_ISO15693(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag) { - uint32_t duration = timestamp_end - timestamp_start; - duration /= 32; - timestamp_end = timestamp_start + duration; - return LogTrace(btBytes, iLen, timestamp_start, timestamp_end, parity, readerToTag); -} - - /////////////////////////////////////////////////////////////////////// // ISO 15693 Part 2 - Air Interface // This section basically contains transmission and receiving of bits /////////////////////////////////////////////////////////////////////// // buffers -#define ISO15693_DMA_BUFFER_SIZE 2048 // must be a power of 2 +#define ISO15693_DMA_BUFFER_SIZE 128 // 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 + +// specific LogTrace function for ISO15693: the duration needs to be scaled because otherwise it won't fit into a uint16_t +bool LogTrace_ISO15693(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag) { + uint32_t duration = timestamp_end - timestamp_start; + duration /= 32; + timestamp_end = timestamp_start + duration; + return LogTrace(btBytes, iLen, timestamp_start, timestamp_end, parity, readerToTag); +} + + // --------------------------- // Signal Processing // --------------------------- @@ -340,6 +341,11 @@ 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. @@ -386,8 +392,8 @@ typedef struct DecodeTag { } DecodeTag_t; -static int inline __attribute__((always_inline)) Handle15693SamplesFromTag(uint16_t amplitude, DecodeTag_t *DecodeTag) { - switch(DecodeTag->state) { +static int inline __attribute__((always_inline)) Handle15693SamplesFromTag(uint16_t amplitude, DecodeTag_t *restrict DecodeTag) { + switch (DecodeTag->state) { case STATE_TAG_SOF_LOW: // waiting for a rising edge if (amplitude > NOISE_THRESHOLD + DecodeTag->previous_amplitude) { @@ -752,11 +758,12 @@ typedef struct DecodeReader { int posCount; int sum1, sum2; uint8_t *output; + uint8_t jam_search_len; + uint8_t *jam_search_string; } DecodeReader_t; -static void DecodeReaderInit(DecodeReader_t* DecodeReader, uint8_t *data, uint16_t max_len) -{ +static void DecodeReaderInit(DecodeReader_t* DecodeReader, uint8_t *data, uint16_t max_len, uint8_t jam_search_len, uint8_t *jam_search_string) { DecodeReader->output = data; DecodeReader->byteCountMax = max_len; DecodeReader->state = STATE_READER_UNSYNCD; @@ -764,17 +771,17 @@ static void DecodeReaderInit(DecodeReader_t* DecodeReader, uint8_t *data, uint16 DecodeReader->bitCount = 0; DecodeReader->posCount = 1; DecodeReader->shiftReg = 0; + DecodeReader->jam_search_len = jam_search_len; + DecodeReader->jam_search_string = jam_search_string; } -static void DecodeReaderReset(DecodeReader_t* DecodeReader) -{ +static void DecodeReaderReset(DecodeReader_t* DecodeReader) { DecodeReader->state = STATE_READER_UNSYNCD; } -static int inline __attribute__((always_inline)) Handle15693SampleFromReader(uint8_t bit, DecodeReader_t *restrict DecodeReader) -{ +static int inline __attribute__((always_inline)) Handle15693SampleFromReader(bool bit, DecodeReader_t *restrict DecodeReader) { switch (DecodeReader->state) { case STATE_READER_UNSYNCD: // wait for unmodulated carrier @@ -889,16 +896,15 @@ static int inline __attribute__((always_inline)) Handle15693SampleFromReader(uin break; case STATE_READER_RECEIVE_DATA_1_OUT_OF_4: - bit = !!bit; DecodeReader->posCount++; if (DecodeReader->posCount == 1) { - DecodeReader->sum1 = bit; + DecodeReader->sum1 = bit?1:0; } else if (DecodeReader->posCount <= 4) { - DecodeReader->sum1 += bit; + if (bit) DecodeReader->sum1++; } else if (DecodeReader->posCount == 5) { - DecodeReader->sum2 = bit; + DecodeReader->sum2 = bit?1:0; } else { - DecodeReader->sum2 += bit; + if (bit) DecodeReader->sum2++; } if (DecodeReader->posCount == 8) { DecodeReader->posCount = 0; @@ -908,13 +914,18 @@ static int inline __attribute__((always_inline)) Handle15693SampleFromReader(uin if (DecodeReader->byteCount != 0) { return true; } - } - if (DecodeReader->sum1 >= 3 && DecodeReader->sum2 <= 1) { // detected a 2bit position + } else if (DecodeReader->sum1 >= 3 && DecodeReader->sum2 <= 1) { // detected a 2bit position DecodeReader->shiftReg >>= 2; DecodeReader->shiftReg |= (DecodeReader->bitCount << 6); } 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(); @@ -929,16 +940,15 @@ static int inline __attribute__((always_inline)) Handle15693SampleFromReader(uin break; case STATE_READER_RECEIVE_DATA_1_OUT_OF_256: - bit = !!bit; DecodeReader->posCount++; if (DecodeReader->posCount == 1) { - DecodeReader->sum1 = bit; + DecodeReader->sum1 = bit?1:0; } else if (DecodeReader->posCount <= 4) { - DecodeReader->sum1 += bit; + if (bit) DecodeReader->sum1++; } else if (DecodeReader->posCount == 5) { - DecodeReader->sum2 = bit; - } else { - DecodeReader->sum2 += bit; + DecodeReader->sum2 = bit?1:0; + } else if (bit) { + DecodeReader->sum2++; } if (DecodeReader->posCount == 8) { DecodeReader->posCount = 0; @@ -948,8 +958,7 @@ static int inline __attribute__((always_inline)) Handle15693SampleFromReader(uin if (DecodeReader->byteCount != 0) { return true; } - } - if (DecodeReader->sum1 >= 3 && DecodeReader->sum2 <= 1) { // detected the bit position + } else if (DecodeReader->sum1 >= 3 && DecodeReader->sum2 <= 1) { // detected the bit position DecodeReader->shiftReg = DecodeReader->bitCount; } if (DecodeReader->bitCount == 255) { // we have a full byte @@ -993,7 +1002,7 @@ int GetIso15693CommandFromReader(uint8_t *received, size_t max_len, uint32_t *eo // the decoder data structure DecodeReader_t DecodeReader = {0}; - DecodeReaderInit(&DecodeReader, received, max_len); + DecodeReaderInit(&DecodeReader, received, max_len, 0, NULL); // wait for last transfer to complete while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXEMPTY)); @@ -1134,10 +1143,10 @@ void AcquireRawAdcSamplesIso15693(void) } -void SnoopIso15693(void) { +void SnoopIso15693(uint8_t jam_search_len, uint8_t *jam_search_string) { LED_A_ON(); - + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); clear_trace(); @@ -1154,9 +1163,9 @@ void SnoopIso15693(void) { uint8_t response[ISO15693_MAX_RESPONSE_LENGTH]; DecodeTagInit(&DecodeTag, response, sizeof(response)); - DecodeReader_t DecodeReader = {0};; + DecodeReader_t DecodeReader = {0}; uint8_t cmd[ISO15693_MAX_COMMAND_LENGTH]; - DecodeReaderInit(&DecodeReader, cmd, sizeof(cmd)); + DecodeReaderInit(&DecodeReader, cmd, sizeof(cmd), jam_search_len, jam_search_string); // Print some debug information about the buffer sizes if (DEBUG) { @@ -1174,17 +1183,22 @@ void SnoopIso15693(void) { FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER); StartCountSspClk(); FpgaSetupSscDma((uint8_t*) dmaBuf, ISO15693_DMA_BUFFER_SIZE); - + bool TagIsActive = false; bool ReaderIsActive = false; bool ExpectTagAnswer = false; uint32_t dma_start_time = 0; uint16_t *upTo = dmaBuf; + + uint16_t max_behindBy = 0; // And now we loop, receiving samples. for(;;) { uint16_t behindBy = ((uint16_t*)AT91C_BASE_PDC_SSC->PDC_RPR - upTo) & (ISO15693_DMA_BUFFER_SIZE-1); - + if (behindBy > max_behindBy) { + max_behindBy = behindBy; + } + if (behindBy == 0) continue; samples++; @@ -1192,12 +1206,13 @@ void SnoopIso15693(void) { // DMA has transferred the very first data dma_start_time = GetCountSspClk() & 0xfffffff0; } - + uint16_t snoopdata = *upTo++; 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(); Dbprintf("About to blow circular buffer - aborted! behindBy=%d, samples=%d", behindBy, samples); break; } @@ -1212,7 +1227,7 @@ void SnoopIso15693(void) { } } - if (!TagIsActive) { // no need to try decoding reader data if the tag is sending + if (!TagIsActive) { // no need to try decoding reader data if the tag is sending if (Handle15693SampleFromReader(snoopdata & 0x02, &DecodeReader)) { // FpgaDisableSscDma(); uint32_t eof_time = dma_start_time + samples*16 + 8 - DELAY_READER_TO_ARM_SNOOP; // end of EOF @@ -1293,12 +1308,15 @@ void SnoopIso15693(void) { LEDsoff(); DbpString("Snoop statistics:"); - Dbprintf(" ExpectTagAnswer: %d", ExpectTagAnswer); + Dbprintf(" ExpectTagAnswer: %d, TagIsActive: %d, ReaderIsActive: %d", ExpectTagAnswer, TagIsActive, ReaderIsActive); Dbprintf(" DecodeTag State: %d", DecodeTag.state); Dbprintf(" DecodeTag byteCnt: %d", DecodeTag.len); + Dbprintf(" DecodeTag posCount: %d", DecodeTag.posCount); Dbprintf(" DecodeReader State: %d", DecodeReader.state); Dbprintf(" DecodeReader byteCnt: %d", DecodeReader.byteCount); + Dbprintf(" DecodeReader posCount: %d", DecodeReader.posCount); Dbprintf(" Trace length: %d", BigBuf_get_traceLen()); + Dbprintf(" Max behindBy: %d", max_behindBy); } @@ -1733,44 +1751,26 @@ void SetTag15693Uid(uint8_t *uid) { LED_A_ON(); - uint8_t cmd[4][9] = {0x00}; + uint8_t cmd[4][9] = { + {0x02, 0x21, 0x3e, 0x00, 0x00, 0x00, 0x00}, + {0x02, 0x21, 0x3f, 0x69, 0x96, 0x00, 0x00}, + {0x02, 0x21, 0x38}, + {0x02, 0x21, 0x39} + }; + uint16_t crc; int recvlen = 0; uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH]; uint32_t eof_time; - // Command 1 : 02213E00000000 - cmd[0][0] = 0x02; - cmd[0][1] = 0x21; - cmd[0][2] = 0x3e; - cmd[0][3] = 0x00; - cmd[0][4] = 0x00; - cmd[0][5] = 0x00; - cmd[0][6] = 0x00; - - // Command 2 : 02213F69960000 - cmd[1][0] = 0x02; - cmd[1][1] = 0x21; - cmd[1][2] = 0x3f; - cmd[1][3] = 0x69; - cmd[1][4] = 0x96; - cmd[1][5] = 0x00; - cmd[1][6] = 0x00; - // Command 3 : 022138u8u7u6u5 (where uX = uid byte X) - cmd[2][0] = 0x02; - cmd[2][1] = 0x21; - cmd[2][2] = 0x38; cmd[2][3] = uid[7]; cmd[2][4] = uid[6]; cmd[2][5] = uid[5]; cmd[2][6] = uid[4]; // Command 4 : 022139u4u3u2u1 (where uX = uid byte X) - cmd[3][0] = 0x02; - cmd[3][1] = 0x21; - cmd[3][2] = 0x39; cmd[3][3] = uid[3]; cmd[3][4] = uid[2]; cmd[3][5] = uid[1]; diff --git a/armsrc/iso15693.h b/armsrc/iso15693.h index 5cbe5ecc..5175ff20 100644 --- a/armsrc/iso15693.h +++ b/armsrc/iso15693.h @@ -31,7 +31,7 @@ void TransmitTo15693Reader(const uint8_t *cmd, size_t len, uint32_t *start_time, int GetIso15693CommandFromReader(uint8_t *received, size_t max_len, uint32_t *eof_time); void TransmitTo15693Tag(const uint8_t *cmd, int len, uint32_t *start_time); int GetIso15693AnswerFromTag(uint8_t* response, uint16_t max_len, uint16_t timeout, uint32_t *eof_time); -void SnoopIso15693(void); +void SnoopIso15693(uint8_t jam_search_len, uint8_t *jam_search_string); void AcquireRawAdcSamplesIso15693(void); void ReaderIso15693(uint32_t parameter); void SimTagIso15693(uint32_t parameter, uint8_t *uid); diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 229af0e1..00493166 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -18,6 +18,7 @@ #include "iso14443crc.h" // Can also be used for iClass, using 0xE012 as CRC-type #include "comms.h" #include "ui.h" +#include "cliparser/cliparser.h" #include "cmdparser.h" #include "cmdhficlass.h" #include "common.h" @@ -175,8 +176,29 @@ static int CmdHFiClassList(const char *Cmd) { static int CmdHFiClassSnoop(const char *Cmd) { - UsbCommand c = {CMD_SNOOP_ICLASS}; + + 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_param_end + }; + if (CLIParserParseString(Cmd, argtable, arg_getsize(argtable), true)){ + CLIParserFree(); + return 0; + } + + bool jam_epurse_update = arg_get_lit(1); + + const uint8_t update_epurse_sequence[2] = {0x87, 0x02}; + + UsbCommand c = {CMD_SNOOP_ICLASS, {0}}; + if (jam_epurse_update) { + c.arg[0] = sizeof(update_epurse_sequence); + memcpy(c.d.asBytes, update_epurse_sequence, sizeof(update_epurse_sequence)); + } SendCommand(&c); + return 0; } diff --git a/common/Makefile.common b/common/Makefile.common index 952a5b9a..116a1b26 100644 --- a/common/Makefile.common +++ b/common/Makefile.common @@ -67,27 +67,31 @@ VPATH = . ../common ../common/crapto1 ../common/mbedtls ../fpga ../zlib INCLUDES = ../include/proxmark3.h ../include/at91sam7s512.h ../include/config_gpio.h ../include/usb_cmd.h $(APP_INCLUDES) -CFLAGS = -c $(INCLUDE) -Wall -Werror -pedantic -std=c99 -Os $(APP_CFLAGS) +CFLAGS = -c $(INCLUDE) -Wall -Werror -pedantic -std=c99 $(APP_CFLAGS) LDFLAGS = -nostartfiles -nodefaultlibs -Wl,-gc-sections -n LIBS = -lgcc THUMBOBJ = $(patsubst %.c,$(OBJDIR)/%.o,$(notdir $(THUMBSRC))) +THUMBOPTOBJ = $(patsubst %.c,$(OBJDIR)/%.o,$(notdir $(THUMBOPTSRC))) ARMOBJ = $(patsubst %.c,$(OBJDIR)/%.o,$(notdir $(ARMSRC))) ASMOBJ = $(patsubst %.s,$(OBJDIR)/%.o,$(notdir $(ASMSRC))) VERSIONOBJ = $(patsubst %.c,$(OBJDIR)/%.o,$(notdir $(VERSIONSRC))) $(THUMBOBJ): $(OBJDIR)/%.o: %.c $(INCLUDES) - $(CC) $(CFLAGS) -mthumb -mthumb-interwork -o $@ $< + $(CC) $(CFLAGS) -Os -mthumb -mthumb-interwork -o $@ $< + +$(THUMBOPTOBJ): $(OBJDIR)/%.o: %.c $(INCLUDES) + $(CC) $(CFLAGS) -O -mthumb -mthumb-interwork -o $@ $< $(ARMOBJ): $(OBJDIR)/%.o: %.c $(INCLUDES) - $(CC) $(CFLAGS) -mthumb-interwork -o $@ $< + $(CC) $(CFLAGS) -Os -mthumb-interwork -o $@ $< $(ASMOBJ): $(OBJDIR)/%.o: %.s - $(CC) $(CFLAGS) -mthumb-interwork -o $@ $< + $(CC) $(CFLAGS) -Os -mthumb-interwork -o $@ $< $(VERSIONOBJ): $(OBJDIR)/%.o: %.c $(INCLUDES) - $(CC) $(CFLAGS) -mthumb -mthumb-interwork -o $@ $< + $(CC) $(CFLAGS) -Os -mthumb -mthumb-interwork -o $@ $< # This objcopy call translates physical flash addresses to logical addresses # without touching start address or RAM addresses (.bss and .data sections) @@ -101,12 +105,13 @@ $(OBJDIR)/%.s19: $(OBJDIR)/%.elf # Automatic dependency generation DEPENDENCY_FILES = $(patsubst %.c,$(OBJDIR)/%.d,$(notdir $(THUMBSRC))) \ + $(patsubst %.c,$(OBJDIR)/%.d,$(notdir $(THUMBOPTSRC))) \ $(patsubst %.c,$(OBJDIR)/%.d,$(notdir $(ARMSRC))) \ $(patsubst %.s,$(OBJDIR)/%.d,$(notdir $(ASMSRC))) $(DEPENDENCY_FILES): Makefile ../common/Makefile.common -$(patsubst %.o,%.d,$(THUMBOBJ) $(ARMOBJ)): $(OBJDIR)/%.d: %.c +$(patsubst %.o,%.d,$(THUMBOBJ) $(THUMBOPTOBJ) $(ARMOBJ)): $(OBJDIR)/%.d: %.c @$(CC) -MM -MT "$(@) $(@:.d=.o)" $(CFLAGS) $< > $@ $(patsubst %.o,%.d,$(ASMOBJ)):$(OBJDIR)/%.d: %.s @$(CC) -MM -MT "$(@) $(@:.d=.o)" $(CFLAGS) $< > $@ diff --git a/common/iso15693tools.c b/common/iso15693tools.c index f1214458..2da6c7f9 100644 --- a/common/iso15693tools.c +++ b/common/iso15693tools.c @@ -7,10 +7,11 @@ //----------------------------------------------------------------------------- +#include "iso15693tools.h" + #include "proxmark3.h" #include #include -//#include "iso15693tools.h" #ifdef ON_DEVICE #include "printf.h" #else @@ -18,24 +19,24 @@ #endif -#define POLY 0x8408 +#define ISO15693_CRC_PRESET (uint16_t)0xFFFF +#define ISO15693_CRC_POLY (uint16_t)0x8408 // The CRC as described in ISO 15693-Part 3-Annex C -// v buffer with data -// n length -// returns crc as 16bit value -uint16_t Iso15693Crc(uint8_t *v, int n) -{ +// v buffer with data +// n length +// returns crc as 16bit value +uint16_t Iso15693Crc(uint8_t *v, int n) { uint32_t reg; int i, j; - reg = 0xffff; - for(i = 0; i < n; i++) { + reg = ISO15693_CRC_PRESET; + for (i = 0; i < n; i++) { reg = reg ^ ((uint32_t)v[i]); for (j = 0; j < 8; j++) { if (reg & 0x0001) { - reg = (reg >> 1) ^ 0x8408; + reg = (reg >> 1) ^ ISO15693_CRC_POLY; } else { reg = (reg >> 1); } @@ -46,55 +47,50 @@ uint16_t Iso15693Crc(uint8_t *v, int n) } // adds a CRC to a dataframe -// req[] iso15963 frame without crc -// n length without crc +// req[] iso15963 frame without crc +// n length without crc // returns the new length of the dataframe. int Iso15693AddCrc(uint8_t *req, int n) { - uint16_t crc=Iso15693Crc(req,n); + uint16_t crc = Iso15693Crc(req, n); req[n] = crc & 0xff; req[n+1] = crc >> 8; - return n+2; + return n + 2; } // returns a string representation of the UID // UID is transmitted and stored LSB first, displayed MSB first -// target char* buffer, where to put the UID, if NULL a static buffer is returned -// uid[] the UID in transmission order -// return: ptr to string -char* Iso15693sprintUID(char *target,uint8_t *uid) { - static char tempbuf[2*8+1]=""; - if (target==NULL) target=tempbuf; - sprintf(target,"%02X%02X%02X%02X%02X%02X%02X%02X", - uid[7],uid[6],uid[5],uid[4],uid[3],uid[2],uid[1],uid[0]); - return target; +// target char* buffer, where to put the UID, if NULL a static buffer is returned +// uid[] the UID in transmission order +// return: ptr to string +char* Iso15693sprintUID(char *target, uint8_t *uid) { + static char tempbuf[2*8+1] = ""; + if (target == NULL) target = tempbuf; + sprintf(target, "%02X%02X%02X%02X%02X%02X%02X%02X", uid[7], uid[6], uid[5], uid[4], uid[3], uid[2], uid[1], uid[0]); + return target; } -uint16_t iclass_crc16(char *data_p, unsigned short length) -{ - unsigned char i; - unsigned int data; - uint16_t crc = 0xffff; - - if (length == 0) - return (~crc); - - do - { - for (i=0, data=(unsigned int)0xff & *data_p++; - i < 8; - i++, data >>= 1) - { - if ((crc & 0x0001) ^ (data & 0x0001)) - crc = (crc >> 1) ^ POLY; - else crc >>= 1; - } - } while (--length); - - crc = ~crc; - data = crc; - crc = (crc << 8) | (data >> 8 & 0xff); - crc = crc ^ 0xBC3; - return (crc); + +uint16_t iclass_crc16(char *data_p, unsigned short length) { + unsigned char i; + unsigned int data; + uint16_t crc = ISO15693_CRC_PRESET; + + if (length == 0) + return (~crc); + + do { + for (i = 0, data = (unsigned int)0xff & *data_p++; i < 8; i++, data >>= 1) { + if ((crc & 0x0001) ^ (data & 0x0001)) + crc = (crc >> 1) ^ ISO15693_CRC_POLY; + else crc >>= 1; + } + } while (--length); + + crc = ~crc; + data = crc; + crc = (crc << 8) | (data >> 8 & 0xff); + crc = crc ^ 0xBC3; + return (crc); } diff --git a/common/iso15693tools.h b/common/iso15693tools.h index ceb6393e..a2eab293 100644 --- a/common/iso15693tools.h +++ b/common/iso15693tools.h @@ -5,8 +5,6 @@ #define ISO15693TOOLS_H__ // ISO15693 CRC -#define ISO15693_CRC_PRESET (uint16_t)0xFFFF -#define ISO15693_CRC_POLY (uint16_t)0x8408 #define ISO15693_CRC_CHECK ((uint16_t)(~0xF0B8 & 0xFFFF)) // use this for checking of a correct crc uint16_t Iso15693Crc(uint8_t *v, int n); diff --git a/fpga/hi_reader.v b/fpga/hi_reader.v index aca9132f..65f1fd35 100644 --- a/fpga/hi_reader.v +++ b/fpga/hi_reader.v @@ -139,7 +139,7 @@ begin // These are the correlators: we correlate against in-phase and quadrature // versions of our reference signal, and keep the (signed) results or the // resulting amplitude to send out later over the SSP. - if(corr_i_cnt == 6'd0) + if (corr_i_cnt == 6'd0) begin if (minor_mode == `FPGA_HF_READER_MODE_SNIFF_AMPLITUDE) begin @@ -213,7 +213,7 @@ begin end // for each Q/I pair report two reader signal samples when sniffing. Store the 2nd. - if(corr_i_cnt == 6'd32) + if (corr_i_cnt == 6'd32) after_hysteresis_prev <= after_hysteresis; // Then the result from last time is serialized and send out to the ARM. @@ -221,10 +221,10 @@ begin // ssp_clk should be the adc_clk divided by 64/16 = 4. // ssp_clk frequency = 13,56MHz / 4 = 3.39MHz - if(corr_i_cnt[1:0] == 2'b00) + if (corr_i_cnt[1:0] == 2'b00) begin // Don't shift if we just loaded new data, obviously. - if(corr_i_cnt != 6'd0) + if (corr_i_cnt != 6'd0) begin corr_i_out[7:0] <= {corr_i_out[6:0], corr_q_out[7]}; corr_q_out[7:1] <= corr_q_out[6:0];