fixing hf 15: implement hf 15 snoop

* rename hf 15 record to hf 15 snoop
* speedup sampling / decoding:
*   new FPGA mode FPGA_HF_READER_RX_XCORR_AMPLITUDE implements amplitude(ci, cq) on FPGA
*   inlining the decoders in iso15693.c
*   inlining memcpy/memset in LogTrace()
*   giving up the moving correlator for SOF in Handle15693SamplesFromTag
* decode more of EOF in Handle15693SamplesFromTag()
* some refactoring
This commit is contained in:
pwpiwi 2018-11-28 08:34:42 +01:00
commit 3de4a49416
16 changed files with 714 additions and 575 deletions

View file

@ -36,8 +36,8 @@ static uint16_t BigBuf_hi = BIGBUF_SIZE;
static uint8_t *emulator_memory = NULL;
// trace related variables
static uint16_t traceLen = 0;
int tracing = 1; //Last global one.. todo static?
static uint32_t traceLen = 0;
static bool tracing = true;
// get the address of BigBuf
uint8_t *BigBuf_get_addr(void)
@ -66,7 +66,7 @@ void BigBuf_Clear(void)
// clear ALL of BigBuf
void BigBuf_Clear_ext(bool verbose)
{
memset(BigBuf,0,BIGBUF_SIZE);
memset(BigBuf, 0, BIGBUF_SIZE);
if (verbose)
Dbprintf("Buffer cleared (%i bytes)",BIGBUF_SIZE);
}
@ -76,7 +76,7 @@ void BigBuf_Clear_EM(void){
void BigBuf_Clear_keep_EM(void)
{
memset(BigBuf,0,BigBuf_hi);
memset(BigBuf, 0, BigBuf_hi);
}
// allocate a chunk of memory from BigBuf. We allocate high memory first. The unallocated memory
@ -162,8 +162,8 @@ bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_
uint8_t *trace = BigBuf_get_addr();
uint16_t num_paritybytes = (iLen-1)/8 + 1; // number of valid paritybytes in *parity
uint16_t duration = timestamp_end - timestamp_start;
uint32_t num_paritybytes = (iLen-1)/8 + 1; // number of valid paritybytes in *parity
uint32_t duration = timestamp_end - timestamp_start;
// Return when trace is full
uint16_t max_traceLen = BigBuf_max_traceLen();
@ -200,19 +200,23 @@ bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_
// data bytes
if (btBytes != NULL && iLen != 0) {
memcpy(trace + traceLen, btBytes, iLen);
for (int i = 0; i < iLen; i++) {
trace[traceLen++] = *btBytes++;
}
}
traceLen += iLen;
// parity bytes
if (num_paritybytes != 0) {
if (parity != NULL) {
memcpy(trace + traceLen, parity, num_paritybytes);
for (int i = 0; i < num_paritybytes; i++) {
trace[traceLen++] = *parity++;
}
} else {
memset(trace + traceLen, 0x00, num_paritybytes);
for (int i = 0; i < num_paritybytes; i++) {
trace[traceLen++] = 0x00;
}
}
}
traceLen += num_paritybytes;
return true;
}
@ -254,8 +258,9 @@ int LogTraceHitag(const uint8_t * btBytes, int iBits, int iSamples, uint32_t dwP
trace[traceLen++] = ((dwParity >> 24) & 0xff);
trace[traceLen++] = iBits;
memcpy(trace + traceLen, btBytes, iLen);
traceLen += iLen;
for (int i = 0; i < iLen; i++) {
trace[traceLen++] = *btBytes++;
}
return true;
}

View file

@ -24,6 +24,7 @@
#include "legicrfsim.h"
#include "hitag2.h"
#include "hitagS.h"
#include "iso15693.h"
#include "lfsampling.h"
#include "BigBuf.h"
#include "mifareutil.h"
@ -1105,8 +1106,9 @@ void UsbPacketReceived(uint8_t *packet, int len)
case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693:
AcquireRawAdcSamplesIso15693();
break;
case CMD_RECORD_RAW_ADC_SAMPLES_ISO_15693:
RecordRawAdcSamplesIso15693();
case CMD_SNOOP_ISO_15693:
SnoopIso15693();
break;
case CMD_ISO_15693_COMMAND:

View file

@ -25,7 +25,6 @@
extern const uint8_t OddByteParity[256];
extern int rsamples; // = 0;
extern int tracing; // = TRUE;
extern uint8_t trigger;
// This may be used (sparingly) to declare a function to be copied to
@ -101,7 +100,6 @@ void RAMFUNC SnoopIso14443b(void);
void SendRawCommand14443B(uint32_t, uint32_t, uint8_t, uint8_t[]);
// Also used in iclass.c
bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t len, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag);
void GetParity(const uint8_t *pbtCmd, uint16_t len, uint8_t *parity);
void RAMFUNC SniffMifare(uint8_t param);
@ -150,15 +148,6 @@ void OnSuccess();
void OnError(uint8_t reason);
/// iso15693.h
void RecordRawAdcSamplesIso15693(void);
void AcquireRawAdcSamplesIso15693(void);
void ReaderIso15693(uint32_t parameter); // Simulate an ISO15693 reader - greg
void SimTagIso15693(uint32_t parameter, uint8_t *uid); // simulate an ISO15693 tag - greg
void BruteforceIso15693Afi(uint32_t speed); // find an AFI of a tag - atrox
void DirectTag15693Command(uint32_t datalen,uint32_t speed, uint32_t recv, uint8_t data[]); // send arbitrary commands from CLI - atrox
void SetDebugIso15693(uint32_t flag);
/// iclass.h
void RAMFUNC SnoopIClass(void);
void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);

View file

@ -24,7 +24,7 @@ void SetupSpi(int mode);
bool FpgaSetupSscDma(uint8_t *buf, uint16_t sample_count);
void Fpga_print_status();
int FpgaGetCurrent();
#define FpgaDisableSscDma(void) AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
#define FpgaDisableSscDma(void) AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
#define FpgaEnableSscDma(void) AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTEN;
void SetAdcMuxFor(uint32_t whichGpio);
@ -33,46 +33,47 @@ void SetAdcMuxFor(uint32_t whichGpio);
#define FPGA_BITSTREAM_HF 2
// Definitions for the FPGA commands.
#define FPGA_CMD_SET_CONFREG (1<<12)
#define FPGA_CMD_SET_DIVISOR (2<<12)
#define FPGA_CMD_SET_USER_BYTE1 (3<<12)
#define FPGA_CMD_SET_CONFREG (1<<12)
#define FPGA_CMD_SET_DIVISOR (2<<12)
#define FPGA_CMD_SET_USER_BYTE1 (3<<12)
// 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<<5)
#define FPGA_MAJOR_MODE_LF_EDGE_DETECT (1<<5)
#define FPGA_MAJOR_MODE_LF_PASSTHRU (2<<5)
// HF
#define FPGA_MAJOR_MODE_HF_READER_TX (0<<5)
#define FPGA_MAJOR_MODE_HF_READER_RX_XCORR (1<<5)
#define FPGA_MAJOR_MODE_HF_SIMULATOR (2<<5)
#define FPGA_MAJOR_MODE_HF_ISO14443A (3<<5)
#define FPGA_MAJOR_MODE_HF_SNOOP (4<<5)
#define FPGA_MAJOR_MODE_HF_READER_TX (0<<5)
#define FPGA_MAJOR_MODE_HF_READER_RX_XCORR (1<<5)
#define FPGA_MAJOR_MODE_HF_SIMULATOR (2<<5)
#define FPGA_MAJOR_MODE_HF_ISO14443A (3<<5)
#define FPGA_MAJOR_MODE_HF_SNOOP (4<<5)
// BOTH
#define FPGA_MAJOR_MODE_OFF (7<<5)
#define FPGA_MAJOR_MODE_OFF (7<<5)
// Options for LF_ADC
#define FPGA_LF_ADC_READER_FIELD (1<<0)
#define FPGA_LF_ADC_READER_FIELD (1<<0)
// Options for LF_EDGE_DETECT
#define FPGA_CMD_SET_EDGE_DETECT_THRESHOLD FPGA_CMD_SET_USER_BYTE1
#define FPGA_LF_EDGE_DETECT_READER_FIELD (1<<0)
#define FPGA_LF_EDGE_DETECT_TOGGLE_MODE (1<<1)
#define FPGA_CMD_SET_EDGE_DETECT_THRESHOLD FPGA_CMD_SET_USER_BYTE1
#define FPGA_LF_EDGE_DETECT_READER_FIELD (1<<0)
#define FPGA_LF_EDGE_DETECT_TOGGLE_MODE (1<<1)
// Options for the HF reader, tx to tag
#define FPGA_HF_READER_TX_SHALLOW_MOD (1<<0)
#define FPGA_HF_READER_TX_SHALLOW_MOD (1<<0)
// Options for the HF reader, correlating against rx from tag
#define FPGA_HF_READER_RX_XCORR_848_KHZ (1<<0)
#define FPGA_HF_READER_RX_XCORR_SNOOP (1<<1)
#define FPGA_HF_READER_RX_XCORR_QUARTER_FREQ (1<<2)
#define FPGA_HF_READER_RX_XCORR_848_KHZ (1<<0)
#define FPGA_HF_READER_RX_XCORR_SNOOP (1<<1)
#define FPGA_HF_READER_RX_XCORR_QUARTER_FREQ (1<<2)
#define FPGA_HF_READER_RX_XCORR_AMPLITUDE (1<<3)
// Options for the HF simulated tag, how to modulate
#define FPGA_HF_SIMULATOR_NO_MODULATION (0<<0)
#define FPGA_HF_SIMULATOR_MODULATE_BPSK (1<<0)
#define FPGA_HF_SIMULATOR_MODULATE_212K (2<<0)
#define FPGA_HF_SIMULATOR_MODULATE_424K (4<<0)
#define FPGA_HF_SIMULATOR_MODULATE_424K_8BIT 0x5//101
#define FPGA_HF_SIMULATOR_NO_MODULATION (0<<0)
#define FPGA_HF_SIMULATOR_MODULATE_BPSK (1<<0)
#define FPGA_HF_SIMULATOR_MODULATE_212K (2<<0)
#define FPGA_HF_SIMULATOR_MODULATE_424K (4<<0)
#define FPGA_HF_SIMULATOR_MODULATE_424K_8BIT 0x5//101
// Options for ISO14443A
#define FPGA_HF_ISO14443A_SNIFFER (0<<0)
#define FPGA_HF_ISO14443A_TAGSIM_LISTEN (1<<0)
#define FPGA_HF_ISO14443A_TAGSIM_MOD (2<<0)
#define FPGA_HF_ISO14443A_READER_LISTEN (3<<0)
#define FPGA_HF_ISO14443A_READER_MOD (4<<0)
#define FPGA_HF_ISO14443A_SNIFFER (0<<0)
#define FPGA_HF_ISO14443A_TAGSIM_LISTEN (1<<0)
#define FPGA_HF_ISO14443A_TAGSIM_MOD (2<<0)
#define FPGA_HF_ISO14443A_READER_LISTEN (3<<0)
#define FPGA_HF_ISO14443A_READER_MOD (4<<0)
#endif

View file

@ -751,12 +751,9 @@ void RAMFUNC SnoopIClass(void)
//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;
if(tracing) {
uint8_t parity[MAX_PARITY_SIZE];
GetParity(Uart.output, Uart.byteCnt, parity);
LogTrace(Uart.output,Uart.byteCnt, time_start, time_stop, parity, true);
}
uint8_t parity[MAX_PARITY_SIZE];
GetParity(Uart.output, Uart.byteCnt, parity);
LogTrace(Uart.output,Uart.byteCnt, time_start, time_stop, parity, true);
/* And ready to receive another command. */
Uart.state = STATE_UNSYNCD;
@ -779,11 +776,9 @@ void RAMFUNC SnoopIClass(void)
rsamples = samples - Demod.samples;
LED_B_ON();
if(tracing) {
uint8_t parity[MAX_PARITY_SIZE];
GetParity(Demod.output, Demod.len, parity);
LogTrace(Demod.output, Demod.len, time_start, time_stop, parity, false);
}
uint8_t parity[MAX_PARITY_SIZE];
GetParity(Demod.output, Demod.len, parity);
LogTrace(Demod.output, Demod.len, time_start, time_stop, parity, false);
// And ready to receive another response.
memset(&Demod, 0, sizeof(Demod));
@ -1322,20 +1317,17 @@ int doIClassSimulation( int simulationMode, uint8_t *reader_mac_buf)
t2r_time = GetCountSspClk();
}
if (tracing) {
uint8_t parity[MAX_PARITY_SIZE];
GetParity(receivedCmd, len, parity);
LogTrace(receivedCmd,len, (r2t_time-time_0)<< 4, (r2t_time-time_0) << 4, parity, true);
if (trace_data != NULL) {
GetParity(trace_data, trace_data_size, parity);
LogTrace(trace_data, trace_data_size, (t2r_time-time_0) << 4, (t2r_time-time_0) << 4, parity, false);
}
if(!tracing) {
DbpString("Trace full");
//break;
}
uint8_t parity[MAX_PARITY_SIZE];
GetParity(receivedCmd, len, parity);
LogTrace(receivedCmd,len, (r2t_time-time_0)<< 4, (r2t_time-time_0) << 4, parity, true);
if (trace_data != NULL) {
GetParity(trace_data, trace_data_size, parity);
LogTrace(trace_data, trace_data_size, (t2r_time-time_0) << 4, (t2r_time-time_0) << 4, parity, false);
}
if(!get_tracing()) {
DbpString("Trace full");
//break;
}
}
@ -1509,11 +1501,9 @@ void ReaderTransmitIClass(uint8_t* frame, int len)
LED_A_ON();
// Store reader command in buffer
if (tracing) {
uint8_t par[MAX_PARITY_SIZE];
GetParity(frame, len, par);
LogTrace(frame, len, rsamples, rsamples, par, true);
}
uint8_t par[MAX_PARITY_SIZE];
GetParity(frame, len, par);
LogTrace(frame, len, rsamples, rsamples, par, true);
}
//-----------------------------------------------------------------------------
@ -1569,11 +1559,9 @@ int ReaderReceiveIClass(uint8_t* receivedAnswer)
int samples = 0;
if (!GetIClassAnswer(receivedAnswer,160,&samples,0)) return false;
rsamples += samples;
if (tracing) {
uint8_t parity[MAX_PARITY_SIZE];
GetParity(receivedAnswer, Demod.len, parity);
LogTrace(receivedAnswer,Demod.len,rsamples,rsamples,parity,false);
}
uint8_t parity[MAX_PARITY_SIZE];
GetParity(receivedAnswer, Demod.len, parity);
LogTrace(receivedAnswer,Demod.len,rsamples,rsamples,parity,false);
if(samples == 0) return false;
return Demod.len;
}
@ -1715,7 +1703,7 @@ void ReaderIClass(uint8_t arg0) {
// if only looking for one card try 2 times if we missed it the first time
if (try_once && tryCnt > 2) break;
tryCnt++;
if(!tracing) {
if(!get_tracing()) {
DbpString("Trace full");
break;
}
@ -1828,7 +1816,7 @@ void ReaderIClass_Replay(uint8_t arg0, uint8_t *MAC) {
WDT_HIT();
if(!tracing) {
if(!get_tracing()) {
DbpString("Trace full");
break;
}

View file

@ -1220,7 +1220,7 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data)
EmSendPrecompiledCmd(p_response);
}
if (!tracing) {
if (!get_tracing()) {
Dbprintf("Trace Full. Simulation stopped.");
break;
}
@ -1619,9 +1619,7 @@ void ReaderTransmitBitsPar(uint8_t* frame, uint16_t bits, uint8_t *par, uint32_t
LED_A_ON();
// Log reader command in trace buffer
if (tracing) {
LogTrace(frame, nbytes(bits), LastTimeProxToAirStart*16 + DELAY_ARM2AIR_AS_READER, (LastTimeProxToAirStart + LastProxToAirDuration)*16 + DELAY_ARM2AIR_AS_READER, par, true);
}
LogTrace(frame, nbytes(bits), LastTimeProxToAirStart*16 + DELAY_ARM2AIR_AS_READER, (LastTimeProxToAirStart + LastProxToAirDuration)*16 + DELAY_ARM2AIR_AS_READER, par, true);
}
@ -1652,9 +1650,7 @@ void ReaderTransmit(uint8_t* frame, uint16_t len, uint32_t *timing)
static int ReaderReceiveOffset(uint8_t* receivedAnswer, uint16_t offset, uint8_t *parity)
{
if (!GetIso14443aAnswerFromTag(receivedAnswer, parity, offset)) return false;
if (tracing) {
LogTrace(receivedAnswer, Demod.len, Demod.startTime*16 - DELAY_AIR2ARM_AS_READER, Demod.endTime*16 - DELAY_AIR2ARM_AS_READER, parity, false);
}
LogTrace(receivedAnswer, Demod.len, Demod.startTime*16 - DELAY_AIR2ARM_AS_READER, Demod.endTime*16 - DELAY_AIR2ARM_AS_READER, parity, false);
return Demod.len;
}
@ -1662,9 +1658,7 @@ static int ReaderReceiveOffset(uint8_t* receivedAnswer, uint16_t offset, uint8_t
int ReaderReceive(uint8_t *receivedAnswer, uint8_t *parity)
{
if (!GetIso14443aAnswerFromTag(receivedAnswer, parity, 0)) return false;
if (tracing) {
LogTrace(receivedAnswer, Demod.len, Demod.startTime*16 - DELAY_AIR2ARM_AS_READER, Demod.endTime*16 - DELAY_AIR2ARM_AS_READER, parity, false);
}
LogTrace(receivedAnswer, Demod.len, Demod.startTime*16 - DELAY_AIR2ARM_AS_READER, Demod.endTime*16 - DELAY_AIR2ARM_AS_READER, parity, false);
return Demod.len;
}

View file

@ -386,10 +386,7 @@ void SimulateIso14443bTag(void)
break;
}
if (tracing) {
uint8_t parity[MAX_PARITY_SIZE];
LogTrace(receivedCmd, len, 0, 0, parity, true);
}
LogTrace(receivedCmd, len, 0, 0, NULL, true);
// Good, look at the command now.
if ( (len == sizeof(cmd1) && memcmp(receivedCmd, cmd1, len) == 0)
@ -463,10 +460,7 @@ void SimulateIso14443bTag(void)
}
// trace the response:
if (tracing) {
uint8_t parity[MAX_PARITY_SIZE];
LogTrace(resp, respLen, 0, 0, parity, false);
}
LogTrace(resp, respLen, 0, 0, NULL, false);
}
}
@ -763,9 +757,8 @@ static void GetSamplesFor14443bDemod(int n, bool quiet)
if (!quiet) Dbprintf("max behindby = %d, samples = %d, gotFrame = %d, Demod.len = %d, Demod.sumI = %d, Demod.sumQ = %d", maxBehindBy, samples, gotFrame, Demod.len, Demod.sumI, Demod.sumQ);
//Tracing
if (tracing && Demod.len > 0) {
uint8_t parity[MAX_PARITY_SIZE];
LogTrace(Demod.output, Demod.len, 0, 0, parity, false);
if (Demod.len > 0) {
LogTrace(Demod.output, Demod.len, 0, 0, NULL, false);
}
}
@ -858,10 +851,7 @@ static void CodeAndTransmit14443bAsReader(const uint8_t *cmd, int len)
{
CodeIso14443bAsReader(cmd, len);
TransmitFor14443b();
if (tracing) {
uint8_t parity[MAX_PARITY_SIZE];
LogTrace(cmd,len, 0, 0, parity, true);
}
LogTrace(cmd,len, 0, 0, NULL, true);
}
/* Sends an APDU to the tag
@ -1153,7 +1143,6 @@ void RAMFUNC SnoopIso14443b(void)
upTo = dmaBuf;
lastRxCounter = ISO14443B_DMA_BUFFER_SIZE;
FpgaSetupSscDma((uint8_t*) dmaBuf, ISO14443B_DMA_BUFFER_SIZE);
uint8_t parity[MAX_PARITY_SIZE];
bool TagIsActive = false;
bool ReaderIsActive = false;
@ -1198,9 +1187,7 @@ void RAMFUNC SnoopIso14443b(void)
if (!TagIsActive) { // no need to try decoding reader data if the tag is sending
if(Handle14443bUartBit(ci & 0x01)) {
triggered = true;
if(tracing) {
LogTrace(Uart.output, Uart.byteCnt, samples, samples, parity, true);
}
LogTrace(Uart.output, Uart.byteCnt, samples, samples, NULL, true);
/* And ready to receive another command. */
UartReset();
/* And also reset the demod code, which might have been */
@ -1209,9 +1196,7 @@ void RAMFUNC SnoopIso14443b(void)
}
if(Handle14443bUartBit(cq & 0x01)) {
triggered = true;
if(tracing) {
LogTrace(Uart.output, Uart.byteCnt, samples, samples, parity, true);
}
LogTrace(Uart.output, Uart.byteCnt, samples, samples, NULL, true);
/* And ready to receive another command. */
UartReset();
/* And also reset the demod code, which might have been */
@ -1223,13 +1208,8 @@ void RAMFUNC SnoopIso14443b(void)
if(!ReaderIsActive && triggered) { // no need to try decoding tag data if the reader is sending or not yet triggered
if(Handle14443bSamplesDemod(ci/2, cq/2)) {
//Use samples as a time measurement
if(tracing)
{
uint8_t parity[MAX_PARITY_SIZE];
LogTrace(Demod.output, Demod.len, samples, samples, parity, false);
}
LogTrace(Demod.output, Demod.len, samples, samples, NULL, false);
// And ready to receive another response.
DemodReset();
}

File diff suppressed because it is too large Load diff

24
armsrc/iso15693.h Normal file
View file

@ -0,0 +1,24 @@
//-----------------------------------------------------------------------------
// Piwi - October 2018
//
// 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 15693.
//-----------------------------------------------------------------------------
#ifndef __ISO15693_H
#define __ISO15693_H
#include <stdint.h>
void SnoopIso15693(void);
void AcquireRawAdcSamplesIso15693(void);
void ReaderIso15693(uint32_t parameter);
void SimTagIso15693(uint32_t parameter, uint8_t *uid);
void BruteforceIso15693Afi(uint32_t speed);
void DirectTag15693Command(uint32_t datalen,uint32_t speed, uint32_t recv, uint8_t data[]);
void SetDebugIso15693(uint32_t flag);
#endif

View file

@ -264,7 +264,7 @@ uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, ui
uint8_t parityBits = parityBytes[j>>3];
if (protocol != ISO_14443B && (isResponse || protocol == ISO_14443A) && (oddparity8(frame[j]) != ((parityBits >> (7-(j&0x0007))) & 0x01))) {
snprintf(line[j/16]+(( j % 16) * 4),110, "%02x! ", frame[j]);
snprintf(line[j/16]+(( j % 16) * 4), 110, " %02x!", frame[j]);
} else {
snprintf(line[j/16]+(( j % 16) * 4), 110, " %02x ", frame[j]);
}
@ -281,14 +281,11 @@ uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, ui
}
}
if(data_len == 0)
{
if(data_len == 0){
sprintf(line[0],"<empty trace - possible error>");
}
if (data_len == 0) {
sprintf(line[0]," <empty trace - possible error>");
}
//--- Draw the CRC column
//--- Draw the CRC column
char *crc = (crcStatus == 0 ? "!crc" : (crcStatus == 1 ? " ok " : " "));
EndOfTransmissionTimestamp = timestamp + duration;

View file

@ -38,15 +38,54 @@
#include "protocols.h"
#include "cmdmain.h"
#define FrameSOF Iso15693FrameSOF
#define Logic0 Iso15693Logic0
#define Logic1 Iso15693Logic1
#define FrameEOF Iso15693FrameEOF
#define Crc(data,datalen) Iso15693Crc(data,datalen)
#define AddCrc(data,datalen) Iso15693AddCrc(data,datalen)
#define sprintUID(target,uid) Iso15693sprintUID(target,uid)
// SOF defined as
// 1) Unmodulated time of 56.64us
// 2) 24 pulses of 423.75khz
// 3) logic '1' (unmodulated for 18.88us followed by 8 pulses of 423.75khz)
static const int Iso15693FrameSOF[] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-1, -1, -1, -1,
-1, -1, -1, -1,
1, 1, 1, 1,
1, 1, 1, 1
};
static const int Iso15693Logic0[] = {
1, 1, 1, 1,
1, 1, 1, 1,
-1, -1, -1, -1,
-1, -1, -1, -1
};
static const int Iso15693Logic1[] = {
-1, -1, -1, -1,
-1, -1, -1, -1,
1, 1, 1, 1,
1, 1, 1, 1
};
// EOF defined as
// 1) logic '0' (8 pulses of 423.75khz followed by unmodulated for 18.88us)
// 2) 24 pulses of 423.75khz
// 3) Unmodulated time of 56.64us
static const int Iso15693FrameEOF[] = {
1, 1, 1, 1,
1, 1, 1, 1,
-1, -1, -1, -1,
-1, -1, -1, -1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
};
// structure and database for uid -> tagtype lookups
typedef struct {
uint64_t uid;
@ -293,8 +332,8 @@ int CmdHF15Demod(const char *Cmd)
// First, correlate for SOF
for (i = 0; i < 200; i++) {
int corr = 0;
for (j = 0; j < arraylen(FrameSOF); j += skip) {
corr += FrameSOF[j] * GraphBuffer[i + (j / skip)];
for (j = 0; j < arraylen(Iso15693FrameSOF); j += skip) {
corr += Iso15693FrameSOF[j] * GraphBuffer[i + (j / skip)];
}
if (corr > max) {
max = corr;
@ -302,28 +341,28 @@ int CmdHF15Demod(const char *Cmd)
}
}
PrintAndLog("SOF at %d, correlation %d", maxPos,
max / (arraylen(FrameSOF) / skip));
max / (arraylen(Iso15693FrameSOF) / skip));
i = maxPos + arraylen(FrameSOF) / skip;
i = maxPos + arraylen(Iso15693FrameSOF) / skip;
int k = 0;
uint8_t outBuf[20];
memset(outBuf, 0, sizeof(outBuf));
uint8_t mask = 0x01;
for (;;) {
int corr0 = 0, corr00 = 0, corr01 = 0, corr1 = 0, corrEOF = 0;
for(j = 0; j < arraylen(Logic0); j += skip) {
corr0 += Logic0[j]*GraphBuffer[i+(j/skip)];
for(j = 0; j < arraylen(Iso15693Logic0); j += skip) {
corr0 += Iso15693Logic0[j]*GraphBuffer[i+(j/skip)];
}
corr01 = corr00 = corr0;
for(j = 0; j < arraylen(Logic0); j += skip) {
corr00 += Logic0[j]*GraphBuffer[i+arraylen(Logic0)/skip+(j/skip)];
corr01 += Logic1[j]*GraphBuffer[i+arraylen(Logic0)/skip+(j/skip)];
for(j = 0; j < arraylen(Iso15693Logic0); j += skip) {
corr00 += Iso15693Logic0[j]*GraphBuffer[i+arraylen(Iso15693Logic0)/skip+(j/skip)];
corr01 += Iso15693Logic1[j]*GraphBuffer[i+arraylen(Iso15693Logic0)/skip+(j/skip)];
}
for(j = 0; j < arraylen(Logic1); j += skip) {
corr1 += Logic1[j]*GraphBuffer[i+(j/skip)];
for(j = 0; j < arraylen(Iso15693Logic1); j += skip) {
corr1 += Iso15693Logic1[j]*GraphBuffer[i+(j/skip)];
}
for(j = 0; j < arraylen(FrameEOF); j += skip) {
corrEOF += FrameEOF[j]*GraphBuffer[i+(j/skip)];
for(j = 0; j < arraylen(Iso15693FrameEOF); j += skip) {
corrEOF += Iso15693FrameEOF[j]*GraphBuffer[i+(j/skip)];
}
// Even things out by the length of the target waveform.
corr00 *= 2;
@ -335,17 +374,17 @@ int CmdHF15Demod(const char *Cmd)
PrintAndLog("EOF at %d", i);
break;
} else if (corr1 > corr0) {
i += arraylen(Logic1) / skip;
i += arraylen(Iso15693Logic1) / skip;
outBuf[k] |= mask;
} else {
i += arraylen(Logic0) / skip;
i += arraylen(Iso15693Logic0) / skip;
}
mask <<= 1;
if (mask == 0) {
k++;
mask = 0x01;
}
if ((i + (int)arraylen(FrameEOF)) >= GraphTraceLen) {
if ((i + (int)arraylen(Iso15693FrameEOF)) >= GraphTraceLen) {
PrintAndLog("ran off end!");
break;
}
@ -374,10 +413,9 @@ int CmdHF15Read(const char *Cmd)
}
// Record Activity without enabling carrier
// TODO: currently it DOES enable the carrier
int CmdHF15Record(const char *Cmd)
int CmdHF15Snoop(const char *Cmd)
{
UsbCommand c = {CMD_RECORD_RAW_ADC_SAMPLES_ISO_15693};
UsbCommand c = {CMD_SNOOP_ISO_15693};
SendCommand(&c);
return 0;
}
@ -514,7 +552,7 @@ static command_t CommandTable15[] =
{"help", CmdHF15Help, 1, "This help"},
{"demod", CmdHF15Demod, 1, "Demodulate ISO15693 from tag"},
{"read", CmdHF15Read, 0, "Read HF tag (ISO 15693)"},
{"record", CmdHF15Record, 0, "Record Samples (ISO 15693)"}, // atrox
{"snoop", CmdHF15Snoop, 0, "Eavesdrop ISO 15693 communications"},
{"reader", CmdHF15Reader, 0, "Act like an ISO15693 reader"},
{"sim", CmdHF15Sim, 0, "Fake an ISO15693 tag"},
{"cmd", CmdHF15Cmd, 0, "Send direct commands to ISO15693 tag"},

View file

@ -14,57 +14,4 @@ int Iso15693AddCrc(uint8_t *req, int n);
char* Iso15693sprintUID(char *target,uint8_t *uid);
unsigned short iclass_crc16(char *data_p, unsigned short length);
//-----------------------------------------------------------------------------
// Map a sequence of octets (~layer 2 command) into the set of bits to feed
// to the FPGA, to transmit that command to the tag.
// Mode: highspeed && one subcarrier (ASK)
//-----------------------------------------------------------------------------
// The sampling rate is 106.353 ksps/s, for T = 18.8 us
// SOF defined as
// 1) Unmodulated time of 56.64us
// 2) 24 pulses of 423.75khz
// 3) logic '1' (unmodulated for 18.88us followed by 8 pulses of 423.75khz)
static const int Iso15693FrameSOF[] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-1, -1, -1, -1,
-1, -1, -1, -1,
1, 1, 1, 1,
1, 1, 1, 1
};
static const int Iso15693Logic0[] = {
1, 1, 1, 1,
1, 1, 1, 1,
-1, -1, -1, -1,
-1, -1, -1, -1
};
static const int Iso15693Logic1[] = {
-1, -1, -1, -1,
-1, -1, -1, -1,
1, 1, 1, 1,
1, 1, 1, 1
};
// EOF defined as
// 1) logic '0' (8 pulses of 423.75khz followed by unmodulated for 18.88us)
// 2) 24 pulses of 423.75khz
// 3) Unmodulated time of 56.64us
static const int Iso15693FrameEOF[] = {
1, 1, 1, 1,
1, 1, 1, 1,
-1, -1, -1, -1,
-1, -1, -1, -1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
};
#endif

Binary file not shown.

View file

@ -75,6 +75,8 @@ wire hi_read_rx_xcorr_848 = conf_word[0];
wire hi_read_rx_xcorr_snoop = conf_word[1];
// divide subcarrier frequency by 4
wire hi_read_rx_xcorr_quarter = conf_word[2];
// send amplitude only instead of ci/cq pair
wire hi_read_rx_xcorr_amplitude = conf_word[3];
// For the high-frequency simulated tag: what kind of modulation to use.
wire [2:0] hi_simulate_mod_type = conf_word[2:0];
@ -102,7 +104,7 @@ hi_read_rx_xcorr hrxc(
hrxc_ssp_frame, hrxc_ssp_din, ssp_dout, hrxc_ssp_clk,
cross_hi, cross_lo,
hrxc_dbg,
hi_read_rx_xcorr_848, hi_read_rx_xcorr_snoop, hi_read_rx_xcorr_quarter
hi_read_rx_xcorr_848, hi_read_rx_xcorr_snoop, hi_read_rx_xcorr_quarter, hi_read_rx_xcorr_amplitude
);
hi_simulate hs(

View file

@ -10,7 +10,7 @@ module hi_read_rx_xcorr(
ssp_frame, ssp_din, ssp_dout, ssp_clk,
cross_hi, cross_lo,
dbg,
xcorr_is_848, snoop, xcorr_quarter_freq
xcorr_is_848, snoop, xcorr_quarter_freq, hi_read_rx_xcorr_amplitude
);
input pck0, ck_1356meg, ck_1356megb;
output pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4;
@ -20,7 +20,7 @@ module hi_read_rx_xcorr(
output ssp_frame, ssp_din, ssp_clk;
input cross_hi, cross_lo;
output dbg;
input xcorr_is_848, snoop, xcorr_quarter_freq;
input xcorr_is_848, snoop, xcorr_quarter_freq, hi_read_rx_xcorr_amplitude;
// Carrier is steady on through this, unless we're snooping.
assign pwr_hi = ck_1356megb & (~snoop);
@ -83,11 +83,46 @@ reg signed [13:0] corr_q_accum;
// we will report maximum 8 significant bits
reg signed [7:0] corr_i_out;
reg signed [7:0] corr_q_out;
// clock and frame signal for communication to ARM
reg ssp_clk;
reg ssp_frame;
// the amplitude of the subcarrier is sqrt(ci^2 + cq^2).
// approximate by amplitude = max(|ci|,|cq|) + 1/2*min(|ci|,|cq|)
reg [13:0] corr_amplitude, abs_ci, abs_cq, max_ci_cq, min_ci_cq;
always @(corr_i_accum or corr_q_accum)
begin
if (corr_i_accum[13] == 1'b0)
abs_ci <= corr_i_accum;
else
abs_ci <= -corr_i_accum;
if (corr_q_accum[13] == 1'b0)
abs_cq <= corr_q_accum;
else
abs_cq <= -corr_q_accum;
if (abs_ci > abs_cq)
begin
max_ci_cq <= abs_ci;
min_ci_cq <= abs_cq;
end
else
begin
max_ci_cq <= abs_cq;
min_ci_cq <= abs_ci;
end
corr_amplitude <= max_ci_cq + min_ci_cq/2;
end
// The subcarrier reference signals
reg subcarrier_I;
reg subcarrier_Q;
@ -111,51 +146,74 @@ begin
end
end
// ADC data appears on the rising edge, so sample it on the falling edge
always @(negedge adc_clk)
begin
// These are the correlators: we correlate against in-phase and quadrature
// versions of our reference signal, and keep the (signed) result to
// send out later over the SSP.
// 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)
begin
if(snoop)
begin
// Send 7 most significant bits of tag signal (signed), plus 1 bit reader signal
if (corr_i_accum[13:11] == 3'b000 || corr_i_accum[13:11] == 3'b111)
corr_i_out <= {corr_i_accum[11:5], after_hysteresis_prev_prev};
else // truncate to maximum value
if (corr_i_accum[13] == 1'b0)
corr_i_out <= {7'b0111111, after_hysteresis_prev_prev};
else
corr_i_out <= {7'b1000000, after_hysteresis_prev_prev};
if (corr_q_accum[13:11] == 3'b000 || corr_q_accum[13:11] == 3'b111)
corr_q_out <= {corr_q_accum[11:5], after_hysteresis_prev};
else // truncate to maximum value
if (corr_q_accum[13] == 1'b0)
corr_q_out <= {7'b0111111, after_hysteresis_prev};
else
corr_q_out <= {7'b1000000, after_hysteresis_prev};
after_hysteresis_prev_prev <= after_hysteresis;
if (hi_read_rx_xcorr_amplitude)
begin
// send amplitude plus 2 bits reader signal
corr_i_out <= corr_amplitude[13:6];
corr_q_out <= {corr_amplitude[5:0], after_hysteresis_prev_prev, after_hysteresis_prev};
end
else
begin
// Send 7 most significant bits of in phase tag signal (signed), plus 1 bit reader signal
if (corr_i_accum[13:11] == 3'b000 || corr_i_accum[13:11] == 3'b111)
corr_i_out <= {corr_i_accum[11:5], after_hysteresis_prev_prev};
else // truncate to maximum value
if (corr_i_accum[13] == 1'b0)
corr_i_out <= {7'b0111111, after_hysteresis_prev_prev};
else
corr_i_out <= {7'b1000000, after_hysteresis_prev_prev};
// Send 7 most significant bits of quadrature phase tag signal (signed), plus 1 bit reader signal
if (corr_q_accum[13:11] == 3'b000 || corr_q_accum[13:11] == 3'b111)
corr_q_out <= {corr_q_accum[11:5], after_hysteresis_prev};
else // truncate to maximum value
if (corr_q_accum[13] == 1'b0)
corr_q_out <= {7'b0111111, after_hysteresis_prev};
else
corr_q_out <= {7'b1000000, after_hysteresis_prev};
end
end
else
begin
// Send 8 bits of tag signal
if (corr_i_accum[13:11] == 3'b000 || corr_i_accum[13:11] == 3'b111)
corr_i_out <= corr_i_accum[11:4];
else // truncate to maximum value
if (corr_i_accum[13] == 1'b0)
corr_i_out <= 8'b01111111;
else
corr_i_out <= 8'b10000000;
if (corr_q_accum[13:11] == 3'b000 || corr_q_accum[13:11] == 3'b111)
corr_q_out <= corr_q_accum[11:4];
else // truncate to maximum value
if (corr_q_accum[13] == 1'b0)
corr_q_out <= 8'b01111111;
else
corr_q_out <= 8'b10000000;
if (hi_read_rx_xcorr_amplitude)
begin
// send amplitude
corr_i_out <= {2'b00, corr_amplitude[13:8]};
corr_q_out <= corr_amplitude[7:0];
end
else
begin
// Send 8 bits of in phase tag signal
if (corr_i_accum[13:11] == 3'b000 || corr_i_accum[13:11] == 3'b111)
corr_i_out <= corr_i_accum[11:4];
else // truncate to maximum value
if (corr_i_accum[13] == 1'b0)
corr_i_out <= 8'b01111111;
else
corr_i_out <= 8'b10000000;
// Send 8 bits of quadrature phase tag signal
if (corr_q_accum[13:11] == 3'b000 || corr_q_accum[13:11] == 3'b111)
corr_q_out <= corr_q_accum[11:4];
else // truncate to maximum value
if (corr_q_accum[13] == 1'b0)
corr_q_out <= 8'b01111111;
else
corr_q_out <= 8'b10000000;
end
end
// for each Q/I pair report two reader signal samples when sniffing. Store the 1st.
after_hysteresis_prev_prev <= after_hysteresis;
// Initialize next correlation.
// Both I and Q reference signals are high when corr_i_nct == 0. Therefore need to accumulate.
corr_i_accum <= $signed({1'b0,adc_d});
@ -172,16 +230,16 @@ begin
corr_q_accum <= corr_q_accum + $signed({1'b0,adc_d});
else
corr_q_accum <= corr_q_accum - $signed({1'b0,adc_d});
end
// for each Q/I pair report two reader signal samples when sniffing
// for each Q/I pair report two reader signal samples when sniffing. Store the 2nd.
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.
// We get one report each cycle, and each report is 16 bits, so the
// 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'b10)
ssp_clk <= 1'b0;

View file

@ -122,7 +122,7 @@ typedef struct{
#define CMD_ISO_14443B_COMMAND 0x0305
#define CMD_READER_ISO_15693 0x0310
#define CMD_SIMTAG_ISO_15693 0x0311
#define CMD_RECORD_RAW_ADC_SAMPLES_ISO_15693 0x0312
#define CMD_SNOOP_ISO_15693 0x0312
#define CMD_ISO_15693_COMMAND 0x0313
#define CMD_ISO_15693_COMMAND_DONE 0x0314
#define CMD_ISO_15693_FIND_AFI 0x0315