hf 14a snoop optimized and added parameters. hf 14a sniff - not work.

This commit is contained in:
Merlokbr@gmail.com 2012-07-07 15:29:51 +00:00
parent b62a5a8444
commit 5cd9ec01e0
5 changed files with 197 additions and 186 deletions

View file

@ -706,7 +706,7 @@ void UsbPacketReceived(uint8_t *packet, int len)
#ifdef WITH_ISO14443a
case CMD_SNOOP_ISO_14443a:
SnoopIso14443a();
SnoopIso14443a(c->arg[0]);
break;
case CMD_READER_ISO_14443a:
ReaderIso14443a(c, &ack);
@ -764,7 +764,7 @@ void UsbPacketReceived(uint8_t *packet, int len)
// mifare sniffer
case CMD_MIFARE_SNIFFER:
SniffMifare();
SniffMifare(c->arg[0]);
break;
#endif

View file

@ -126,16 +126,16 @@ void ReadSTMemoryIso14443(uint32_t parameter,uint32_t dwLast);
void RAMFUNC SnoopIso14443(void);
/// iso14443a.h
void RAMFUNC SnoopIso14443a(void);
void RAMFUNC SnoopIso14443a(uint8_t param);
void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd); // ## simulate iso14443a tag
void ReaderIso14443a(UsbCommand * c, UsbCommand * ack);
// Also used in iclass.c
int LogTrace(const uint8_t * btBytes, int iLen, int iSamples, uint32_t dwParity, int bReader);
int RAMFUNC LogTrace(const uint8_t * btBytes, int iLen, int iSamples, uint32_t dwParity, int bReader);
uint32_t GetParity(const uint8_t * pbtCmd, int iLen);
void iso14a_set_trigger(int enable);
void iso14a_clear_tracelen(void);
void iso14a_set_tracing(int enable);
void RAMFUNC SniffMifare(void);
void RAMFUNC SniffMifare(uint8_t param);
// mifarecmd.h
void ReaderMifare(uint32_t parameter);

View file

@ -101,7 +101,7 @@ void AppendCrc14443a(uint8_t* data, int len)
}
// The function LogTrace() is also used by the iClass implementation in iClass.c
int LogTrace(const uint8_t * btBytes, int iLen, int iSamples, uint32_t dwParity, int bReader)
int RAMFUNC LogTrace(const uint8_t * btBytes, int iLen, int iSamples, uint32_t dwParity, int bReader)
{
// Return when trace is full
if (traceLen >= TRACE_SIZE) return FALSE;
@ -568,166 +568,149 @@ static RAMFUNC int ManchesterDecoding(int v)
// triggering so that we start recording at the point that the tag is moved
// near the reader.
//-----------------------------------------------------------------------------
void RAMFUNC SnoopIso14443a(void)
{
// #define RECV_CMD_OFFSET 2032 // original (working as of 21/2/09) values
// #define RECV_RES_OFFSET 2096 // original (working as of 21/2/09) values
// #define DMA_BUFFER_OFFSET 2160 // original (working as of 21/2/09) values
// #define DMA_BUFFER_SIZE 4096 // original (working as of 21/2/09) values
// #define TRACE_SIZE 2000 // original (working as of 21/2/09) values
void RAMFUNC SnoopIso14443a(uint8_t param) {
// param:
// bit 0 - trigger from first card answer
// bit 1 - trigger from first reader 7-bit request
LEDsoff();
// init trace buffer
traceLen = 0;
memset(trace, 0x44, TRACE_SIZE);
// 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
// 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.
// triggered == FALSE -- to wait first for card
int triggered = !(param & 0x03);
// The command (reader -> tag) that we're receiving.
// 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!
uint8_t *receivedCmd = (((uint8_t *)BigBuf) + RECV_CMD_OFFSET);
// The response (tag -> reader) that we're receiving.
uint8_t *receivedResponse = (((uint8_t *)BigBuf) + RECV_RES_OFFSET);
uint8_t *receivedCmd = (((uint8_t *)BigBuf) + RECV_CMD_OFFSET);
// The response (tag -> reader) that we're receiving.
uint8_t *receivedResponse = (((uint8_t *)BigBuf) + RECV_RES_OFFSET);
// As we receive stuff, we copy it from receivedCmd or receivedResponse
// into trace, along with its length and other annotations.
//uint8_t *trace = (uint8_t *)BigBuf;
traceLen = 0; // uncommented to fix ISSUE 15 - gerhard - jan2011
// As we receive stuff, we copy it from receivedCmd or receivedResponse
// into trace, along with its length and other annotations.
//uint8_t *trace = (uint8_t *)BigBuf;
// The DMA buffer, used to stream samples from the FPGA
int8_t *dmaBuf = ((int8_t *)BigBuf) + DMA_BUFFER_OFFSET;
int8_t *data = dmaBuf;
int maxDataLen = 0;
int dataLen = 0;
// The DMA buffer, used to stream samples from the FPGA
int8_t *dmaBuf = ((int8_t *)BigBuf) + DMA_BUFFER_OFFSET;
int lastRxCounter;
int8_t *upTo;
int smpl;
int maxBehindBy = 0;
// Set up the demodulator for tag -> reader responses.
Demod.output = receivedResponse;
Demod.len = 0;
Demod.state = DEMOD_UNSYNCD;
// Count of samples received so far, so that we can include timing
// information in the trace buffer.
int samples = 0;
int rsamples = 0;
// Set up the demodulator for the reader -> tag commands
memset(&Uart, 0, sizeof(Uart));
Uart.output = receivedCmd;
Uart.byteCntMax = 32; // was 100 (greg)//////////////////
Uart.state = STATE_UNSYNCD;
memset(trace, 0x44, TRACE_SIZE);
// Setup for the DMA.
FpgaSetupSsc();
FpgaSetupSscDma((uint8_t *)dmaBuf, DMA_BUFFER_SIZE);
// Set up the demodulator for tag -> reader responses.
Demod.output = receivedResponse;
Demod.len = 0;
Demod.state = DEMOD_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);
// Setup for the DMA.
FpgaSetupSsc();
upTo = dmaBuf;
lastRxCounter = DMA_BUFFER_SIZE;
FpgaSetupSscDma((uint8_t *)dmaBuf, DMA_BUFFER_SIZE);
// Count of samples received so far, so that we can include timing
// information in the trace buffer.
rsamples = 0;
// And now we loop, receiving samples.
while(true) {
if(BUTTON_PRESS()) {
DbpString("cancelled by button");
goto done;
}
// And the reader -> tag commands
memset(&Uart, 0, sizeof(Uart));
Uart.output = receivedCmd;
Uart.byteCntMax = 32; // was 100 (greg)////////////////////////////////////////////////////////////////////////
Uart.state = STATE_UNSYNCD;
LED_A_ON();
WDT_HIT();
// 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);
int register readBufDataP = data - dmaBuf;
int register dmaBufDataP = DMA_BUFFER_SIZE - AT91C_BASE_PDC_SSC->PDC_RCR;
if (readBufDataP <= dmaBufDataP){
dataLen = dmaBufDataP - readBufDataP;
} else {
dataLen = DMA_BUFFER_SIZE - readBufDataP + dmaBufDataP + 1;
}
// test for length of buffer
if(dataLen > maxDataLen) {
maxDataLen = dataLen;
if(dataLen > 400) {
Dbprintf("blew circular buffer! dataLen=0x%x", dataLen);
goto done;
}
}
if(dataLen < 1) continue;
// primary buffer was stopped( <-- we lost data!
if (!AT91C_BASE_PDC_SSC->PDC_RCR) {
AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) dmaBuf;
AT91C_BASE_PDC_SSC->PDC_RCR = DMA_BUFFER_SIZE;
Dbprintf("RxEmpty ERROR!!! %d", dataLen); // temporary
}
// secondary buffer sets as primary, secondary buffer was stopped
if (!AT91C_BASE_PDC_SSC->PDC_RNCR) {
AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dmaBuf;
AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE;
}
// 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 > 400) {
Dbprintf("blew circular buffer! behindBy=0x%x", behindBy);
goto done;
}
}
if(behindBy < 1) continue;
LED_A_OFF();
rsamples += 4;
if(MillerDecoding((data[0] & 0xF0) >> 4)) {
LED_C_ON();
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;
}
// check - if there is a short 7bit request from reader
if ((!triggered) && (param & 0x02) && (Uart.byteCnt == 1) && (Uart.bitCnt = 9)) triggered = TRUE;
samples += 4;
if(MillerDecoding((smpl & 0xF0) >> 4)) {
rsamples = samples - Uart.samples;
LED_C_ON();
if(triggered) {
trace[traceLen++] = ((rsamples >> 0) & 0xff);
trace[traceLen++] = ((rsamples >> 8) & 0xff);
trace[traceLen++] = ((rsamples >> 16) & 0xff);
trace[traceLen++] = ((rsamples >> 24) & 0xff);
trace[traceLen++] = ((Uart.parityBits >> 0) & 0xff);
trace[traceLen++] = ((Uart.parityBits >> 8) & 0xff);
trace[traceLen++] = ((Uart.parityBits >> 16) & 0xff);
trace[traceLen++] = ((Uart.parityBits >> 24) & 0xff);
trace[traceLen++] = Uart.byteCnt;
memcpy(trace+traceLen, receivedCmd, Uart.byteCnt);
traceLen += Uart.byteCnt;
if(traceLen > TRACE_SIZE) break;
}
/* 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;
LED_B_OFF();
}
if(triggered) {
if (!LogTrace(receivedCmd, Uart.byteCnt, 0 - Uart.samples, Uart.parityBits, TRUE)) break;
}
/* 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;
LED_B_OFF();
}
if(ManchesterDecoding(smpl & 0x0F)) {
rsamples = samples - Demod.samples;
LED_B_ON();
if(ManchesterDecoding(data[0] & 0x0F)) {
LED_B_ON();
// timestamp, as a count of samples
trace[traceLen++] = ((rsamples >> 0) & 0xff);
trace[traceLen++] = ((rsamples >> 8) & 0xff);
trace[traceLen++] = ((rsamples >> 16) & 0xff);
trace[traceLen++] = 0x80 | ((rsamples >> 24) & 0xff);
trace[traceLen++] = ((Demod.parityBits >> 0) & 0xff);
trace[traceLen++] = ((Demod.parityBits >> 8) & 0xff);
trace[traceLen++] = ((Demod.parityBits >> 16) & 0xff);
trace[traceLen++] = ((Demod.parityBits >> 24) & 0xff);
// length
trace[traceLen++] = Demod.len;
memcpy(trace+traceLen, receivedResponse, Demod.len);
traceLen += Demod.len;
if(traceLen > TRACE_SIZE) break;
if (!LogTrace(receivedResponse, Demod.len, 0 - Demod.samples, Demod.parityBits, FALSE)) break;
triggered = TRUE;
if ((!triggered) && (param & 0x01)) triggered = TRUE;
// And ready to receive another response.
memset(&Demod, 0, sizeof(Demod));
Demod.output = receivedResponse;
Demod.state = DEMOD_UNSYNCD;
LED_C_OFF();
}
// And ready to receive another response.
memset(&Demod, 0, sizeof(Demod));
Demod.output = receivedResponse;
Demod.state = DEMOD_UNSYNCD;
LED_C_OFF();
}
if(BUTTON_PRESS()) {
DbpString("cancelled_a");
goto done;
}
}
data++;
if(data > dmaBuf + DMA_BUFFER_SIZE) {
data = dmaBuf;
}
} // main cycle
DbpString("COMMAND FINISHED");
DbpString("COMMAND FINISHED");
done:
AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
Dbprintf("maxBehindBy=%x, Uart.state=%x, Uart.byteCnt=%x", maxBehindBy, Uart.state, Uart.byteCnt);
Dbprintf("Uart.byteCntMax=%x, traceLen=%x, Uart.output[0]=%x", Uart.byteCntMax, traceLen, (int)Uart.output[0]);
LED_A_OFF();
LED_B_OFF();
LED_C_OFF();
LED_D_OFF();
AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
Dbprintf("maxDataLen=%x, Uart.state=%x, Uart.byteCnt=%x", maxDataLen, Uart.state, Uart.byteCnt);
Dbprintf("Uart.byteCntMax=%x, traceLen=%x, Uart.output[0]=%08x", Uart.byteCntMax, traceLen, (int)Uart.output[0]);
LEDsoff();
}
//-----------------------------------------------------------------------------
@ -2369,17 +2352,16 @@ lbWORK: if (len == 0) break;
// MIFARE sniffer.
//
//-----------------------------------------------------------------------------
void RAMFUNC SniffMifare(void) {
void RAMFUNC SniffMifare(uint8_t param) {
// param:
// bit 0 - trigger from first card answer
// bit 1 - trigger from first reader 7-bit request
LEDsoff();
// init trace buffer
traceLen = 0;
memset(trace, 0x44, TRACE_SIZE);
// 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!
@ -2393,10 +2375,10 @@ void RAMFUNC SniffMifare(void) {
// The DMA buffer, used to stream samples from the FPGA
int8_t *dmaBuf = ((int8_t *)BigBuf) + DMA_BUFFER_OFFSET;
int lastRxCounter;
int8_t *upTo;
int smpl;
int maxBehindBy = 0;
int8_t *data = dmaBuf;
int maxDataLen = 0;
int dataLen = 0;
// data = dmaBuf;
// Set up the demodulator for tag -> reader responses.
Demod.output = receivedResponse;
@ -2411,8 +2393,6 @@ void RAMFUNC SniffMifare(void) {
// Setup for the DMA.
FpgaSetupSsc();
upTo = dmaBuf;
lastRxCounter = DMA_BUFFER_SIZE;
FpgaSetupSscDma((uint8_t *)dmaBuf, DMA_BUFFER_SIZE);
// And put the FPGA in the appropriate mode
@ -2426,37 +2406,54 @@ void RAMFUNC SniffMifare(void) {
rsamples = 0;
// And now we loop, receiving samples.
while(true) {
if(BUTTON_PRESS()) {
DbpString("cancelled by button");
goto done;
}
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 > 400) {
Dbprintf("blew circular buffer! behindBy=0x%x", behindBy);
int register readBufDataP = data - dmaBuf;
int register dmaBufDataP = DMA_BUFFER_SIZE - AT91C_BASE_PDC_SSC->PDC_RCR;
if (readBufDataP <= dmaBufDataP){
dataLen = dmaBufDataP - readBufDataP;
} else {
dataLen = DMA_BUFFER_SIZE - readBufDataP + dmaBufDataP + 1;
}
// test for length of buffer
if(dataLen > maxDataLen) {
maxDataLen = dataLen;
if(dataLen > 400) {
Dbprintf("blew circular buffer! dataLen=0x%x", dataLen);
goto done;
}
}
if(behindBy < 1) continue;
if(dataLen < 1) continue;
// primary buffer was stopped( <-- we lost data!
if (!AT91C_BASE_PDC_SSC->PDC_RCR) {
AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) dmaBuf;
AT91C_BASE_PDC_SSC->PDC_RCR = DMA_BUFFER_SIZE;
Dbprintf("RxEmpty ERROR!!! %d", dataLen); // temporary
}
// secondary buffer sets as primary, secondary buffer was stopped
if (!AT91C_BASE_PDC_SSC->PDC_RNCR) {
AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dmaBuf;
AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE;
}
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;
}
rsamples += 4;
if(MillerDecoding((smpl & 0xF0) >> 4)) {
if(MillerDecoding((data[0] & 0xF0) >> 4)) {
LED_C_ON();
if(triggered) {
if (!LogTrace(receivedCmd, Uart.byteCnt, -1 * Uart.samples, Uart.parityBits, TRUE)) break;
// check - if there is a short 7bit request from reader
if ((Uart.byteCnt == 1) && (Uart.bitCnt = 9)) {
}
if (!LogTrace(receivedCmd, Uart.byteCnt, 0 - Uart.samples, Uart.parityBits, TRUE)) break;
/* And ready to receive another command. */
Uart.state = STATE_UNSYNCD;
/* And also reset the demod code, which might have been */
@ -2465,12 +2462,10 @@ void RAMFUNC SniffMifare(void) {
LED_B_OFF();
}
if(ManchesterDecoding(smpl & 0x0F)) {
if(ManchesterDecoding(data[0] & 0x0F)) {
LED_B_ON();
if (!LogTrace(receivedResponse, Demod.len, -1 * Demod.samples, Demod.parityBits, FALSE)) break;
triggered = TRUE;
if (!LogTrace(receivedResponse, Demod.len, 0 - Demod.samples, Demod.parityBits, FALSE)) break;
// And ready to receive another response.
memset(&Demod, 0, sizeof(Demod));
@ -2479,9 +2474,9 @@ void RAMFUNC SniffMifare(void) {
LED_C_OFF();
}
if(BUTTON_PRESS()) {
DbpString("button cancelled");
goto done;
data++;
if(data > dmaBuf + DMA_BUFFER_SIZE) {
data = dmaBuf;
}
} // main cycle
@ -2489,7 +2484,7 @@ void RAMFUNC SniffMifare(void) {
done:
AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
Dbprintf("maxBehindBy=%x, Uart.state=%x, Uart.byteCnt=%x", maxBehindBy, Uart.state, Uart.byteCnt);
Dbprintf("maxDataLen=%x, Uart.state=%x, Uart.byteCnt=%x", maxDataLen, Uart.state, Uart.byteCnt);
Dbprintf("Uart.byteCntMax=%x, traceLen=%x, Uart.output[0]=%x", Uart.byteCntMax, traceLen, (int)Uart.output[0]);
LEDsoff();
}

View file

@ -93,6 +93,5 @@ extern void iso14a_set_trigger(int enable);
extern void iso14a_clear_tracelen(void);
extern void iso14a_set_tracing(int enable);
extern int LogTrace(const uint8_t * btBytes, int iLen, int iSamples, uint32_t dwParity, int bReader);
#endif /* __ISO14443A_H */

View file

@ -284,9 +284,26 @@ int CmdHF14ASim(const char *Cmd)
return 0;
}
int CmdHF14ASnoop(const char *Cmd)
{
UsbCommand c = {CMD_SNOOP_ISO_14443a};
int CmdHF14ASnoop(const char *Cmd) {
int param = 0;
if (param_getchar(Cmd, 0) == 'h') {
PrintAndLog("It get data from the field and saves it into command buffer.");
PrintAndLog("Buffer accessible from command hf 14a list.");
PrintAndLog("Usage: hf 14a snoop [c][r]");
PrintAndLog("c - triggered by first data from card");
PrintAndLog("r - triggered by first 7-bit request from reader (REQ,WUP,...)");
PrintAndLog("sample: hf 14a snoop c r");
return 0;
}
for (int i = 0; i < 2; i++) {
char ctmp = param_getchar(Cmd, i);
if (ctmp == 'c' || ctmp == 'C') param |= 0x01;
if (ctmp == 'r' || ctmp == 'R') param |= 0x02;
}
UsbCommand c = {CMD_SNOOP_ISO_14443a, {param, 0, 0}};
SendCommand(&c);
return 0;
}