'hf 14b sniff' - removed stuff which wasn't very useful. cleaner now. Not sure if it works :(

'hf iclass sniff' - playing with this one.  Don't expect it to work yet :(
   - increase dma_buffer_size to 256
   - moved initialization to a own function. Just looks cleaner :)
   - change the debug output to follow MF_DBGLEVEL
'hf mf sniff' - unnecessary cast removed
This commit is contained in:
iceman1001 2017-08-27 19:41:24 +02:00
commit 292a4ca602
5 changed files with 139 additions and 198 deletions

View file

@ -54,6 +54,16 @@ static int SendIClassAnswer(uint8_t *resp, int respLen, int delay);
#define MODE_EXIT_AFTER_MAC 1 #define MODE_EXIT_AFTER_MAC 1
#define MODE_FULLSIM 2 #define MODE_FULLSIM 2
#ifndef ICLASS_DMA_BUFFER_SIZE
# define ICLASS_DMA_BUFFER_SIZE 256
#endif
// The length of a received command will in most cases be no more than 18 bytes.
// 32 should be enough!
#ifndef ICLASS_BUFFER_SIZE
#define ICLASS_BUFFER_SIZE 32
#endif
int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf); int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf);
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -656,6 +666,46 @@ static RAMFUNC int ManchesterDecoding(int v) {
// Both sides of communication! // Both sides of communication!
//============================================================================= //=============================================================================
static void iclass_setup_sniff(void){
if (MF_DBGLEVEL > 3) Dbprintf("iclass_setup_sniff Enter");
LEDsoff();
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
BigBuf_free(); BigBuf_Clear_ext(false);
clear_trace();
set_tracing(true);
// Initialize Demod and Uart structs
DemodInit(BigBuf_malloc(ICLASS_BUFFER_SIZE));
UartInit(BigBuf_malloc(ICLASS_BUFFER_SIZE));
if (MF_DBGLEVEL > 1) {
// Print debug information about the buffer sizes
Dbprintf("Snooping buffers initialized:");
Dbprintf(" Trace: %i bytes", BigBuf_max_traceLen());
Dbprintf(" Reader -> tag: %i bytes", ICLASS_BUFFER_SIZE);
Dbprintf(" tag -> Reader: %i bytes", ICLASS_BUFFER_SIZE);
Dbprintf(" DMA: %i bytes", ICLASS_DMA_BUFFER_SIZE);
}
// connect Demodulated Signal to ADC:
SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
// Set up the synchronous serial port
FpgaSetupSsc();
// Set FPGA in the appropriate mode
// put the FPGA in the appropriate mode
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_SNIFFER);
SpinDelay(50);
// Start the SSP timer
StartCountSspClk();
if (MF_DBGLEVEL > 3) Dbprintf("iclass_setup_sniff Exit");
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Record the sequence of commands sent by the reader to the tag, with // 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 // triggering so that we start recording at the point that the tag is moved
@ -664,199 +714,129 @@ static RAMFUNC int ManchesterDecoding(int v) {
// turn off afterwards // turn off afterwards
void RAMFUNC SniffIClass(void) { void RAMFUNC SniffIClass(void) {
LEDsoff();
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
// Set up the synchronous serial port
FpgaSetupSsc();
// connect Demodulated Signal to ADC:
SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
// Signal field is off with the appropriate LED
LED_D_OFF();
// put the FPGA in the appropriate mode
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_SNIFFER);
SpinDelay(50);
// Start the timer
StartCountSspClk();
// free all BigBuf memory
BigBuf_free(); BigBuf_Clear_ext(false);
clear_trace();
set_tracing(true);
// 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.
// 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 = BigBuf_malloc(ICLASS_BUFFER_SIZE);
// The response (tag -> reader) that we're receiving.
uint8_t *tagToReaderResponse = BigBuf_malloc(ICLASS_BUFFER_SIZE);
// The DMA buffer, used to stream samples from the FPGA
uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE);
uint8_t *data = dmaBuf;
uint8_t previous_data = 0; uint8_t previous_data = 0;
int maxDataLen = 0; int maxDataLen = 0, datalen = 0;
int datalen = 0; uint32_t time_0 = 0, time_start = 0, time_stop = 0;
uint32_t sniffCounter = 0;
bool TagIsActive = false; bool TagIsActive = false;
bool ReaderIsActive = false; bool ReaderIsActive = false;
// Set up the demodulator for tag -> reader responses. iclass_setup_sniff();
DemodInit(tagToReaderResponse);
// And the reader -> tag commands // The DMA buffer, used to stream samples from the FPGA
UartInit(readerToTagCmd); uint8_t *dmaBuf = BigBuf_malloc(ICLASS_DMA_BUFFER_SIZE);
uint8_t *data = dmaBuf;
// Setup and start DMA. // Setup and start DMA.
if ( !FpgaSetupSscDma((uint8_t*) dmaBuf, DMA_BUFFER_SIZE) ){ if ( !FpgaSetupSscDma(dmaBuf, ICLASS_DMA_BUFFER_SIZE) ){
if (MF_DBGLEVEL > 1) DbpString("FpgaSetupSscDma failed. Exiting"); if (MF_DBGLEVEL > 1) DbpString("FpgaSetupSscDma failed. Exiting");
return; return;
} }
uint32_t time_0 = GetCountSspClk(); // time ZERO, the point from which it all is calculated.
uint32_t time_start = 0, time_stop = 0; time_0 = GetCountSspClk();
int div = 0;
uint32_t rsamples = 0;
DbpString("Starting to sniff");
// loop and listen // loop and listen
while (!BUTTON_PRESS()) { while (!BUTTON_PRESS()) {
WDT_HIT(); WDT_HIT();
LED_A_ON();
previous_data = *data;
sniffCounter++;
data++;
if (data == dmaBuf + ICLASS_DMA_BUFFER_SIZE) {
data = dmaBuf;
AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dmaBuf;
AT91C_BASE_PDC_SSC->PDC_RNCR = ICLASS_DMA_BUFFER_SIZE;
}
// number of bytes we have processed so far // number of bytes we have processed so far
int register readBufDataP = data - dmaBuf; //int register readBufDataP = data - dmaBuf;
// number of bytes already transferred // number of bytes already transferred
int register dmaBufDataP = DMA_BUFFER_SIZE - AT91C_BASE_PDC_SSC->PDC_RCR; //int register dmaBufDataP = ICLASS_DMA_BUFFER_SIZE - AT91C_BASE_PDC_SSC->PDC_RCR;
/*
if (readBufDataP <= dmaBufDataP) if (readBufDataP <= dmaBufDataP)
datalen = dmaBufDataP - readBufDataP; datalen = dmaBufDataP - readBufDataP;
else else
datalen = DMA_BUFFER_SIZE - readBufDataP + dmaBufDataP; datalen = ICLASS_DMA_BUFFER_SIZE - readBufDataP + dmaBufDataP;
*/
// test for length of buffer // test for length of buffer
/*
if (datalen > maxDataLen) { if (datalen > maxDataLen) {
maxDataLen = datalen; maxDataLen = datalen;
if (datalen > (9 * DMA_BUFFER_SIZE / 10)) { if (datalen > (9 * ICLASS_DMA_BUFFER_SIZE / 10)) {
Dbprintf("blew circular buffer! datalen=%d", datalen); Dbprintf("blew circular buffer! datalen=%d", datalen);
break; break;
} }
} }
if (datalen < 1) continue; */
// this part basically does wait until our DMA buffer got a value.
// well it loops, but the purpose is to wait.
//if (datalen < 1) continue;
// these two, is more of a "reset" the DMA buffers, re-init.
// primary buffer was stopped( <-- we lost data! // primary buffer was stopped( <-- we lost data!
/*
if (!AT91C_BASE_PDC_SSC->PDC_RCR) { if (!AT91C_BASE_PDC_SSC->PDC_RCR) {
AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) dmaBuf; AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) dmaBuf;
AT91C_BASE_PDC_SSC->PDC_RCR = DMA_BUFFER_SIZE; AT91C_BASE_PDC_SSC->PDC_RCR = ICLASS_DMA_BUFFER_SIZE;
Dbprintf("RxEmpty ERROR!!! data length:%d", datalen); // temporary // Dbprintf("Primary buffer ERROR!!! data length: %d", datalen); // temporary
} }
*/
/*
// secondary buffer sets as primary, secondary buffer was stopped // secondary buffer sets as primary, secondary buffer was stopped
if (!AT91C_BASE_PDC_SSC->PDC_RNCR) { if (!AT91C_BASE_PDC_SSC->PDC_RNCR) {
AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dmaBuf; AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dmaBuf;
AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE; AT91C_BASE_PDC_SSC->PDC_RNCR = ICLASS_DMA_BUFFER_SIZE;
} // Dbprintf("Seconday buffer ERROR!!! data length: %d", datalen); // temporary
}*/
LED_A_OFF();
div++;
//
Dbprintf("iced: prev %, curr %u, div %i", previous_data, *data, div);
// need two samples to feed OutOfNDecoding
if (rsamples & 0x01) {
if (sniffCounter & 0x01) {
// no need to try decoding reader data if the tag is sending // no need to try decoding reader data if the tag is sending
// READER TO CARD // READER TO CARD
if (!TagIsActive) { if (!TagIsActive) {
if (MF_DBGLEVEL > 1) DbpString("reader -> card");
uint8_t readerdata = (previous_data & 0xF0) | (*data >> 4);
// FOR READER SIDE COMMUMICATION...
//readerbyte <<= 2; // make space for two new bits.
// 76543210
// xor ( sample & 00110000 ) only bit 5,4 wanted. ( one out of four?
//readerbyte ^= (sample & 0x30);
// 00110000 -> 0011
if ( OutOfNDecoding((readerdata & 0xF0) >> 4)) {
LED_C_INV(); LED_C_INV();
// HIGH nibble is always reader data.
time_stop = (GetCountSspClk() - time_0) << 4; uint8_t readerdata = (previous_data & 0xF0) | (*data >> 4);
if ( OutOfNDecoding(readerdata) ) {
time_stop = GetCountSspClk() - time_0;
LogTrace(Uart.output, Uart.byteCnt, time_start, time_stop, NULL, true); LogTrace(Uart.output, Uart.byteCnt, time_start, time_stop, NULL, true);
// reset the demod code, which might have been false-triggered by the commands from the reader.
DemodReset(); DemodReset();
// ready to receive another command. UartReset();
UartInit(readerToTagCmd);
} else { } else {
time_start = (GetCountSspClk() - time_0) << 4; time_start = GetCountSspClk() - time_0;
} }
//readerbyte = 0;
ReaderIsActive = (Uart.state != STATE_UNSYNCD); ReaderIsActive = (Uart.state != STATE_UNSYNCD);
} }
} }
if ( sniffCounter % 3) {
if (div > 3) { // need two samples to feed Manchester
if (MF_DBGLEVEL > 1) DbpString("div > 3");
// no need to try decoding tag data if the reader is sending - and we cannot afford the time // no need to try decoding tag data if the reader is sending - and we cannot afford the time
// CARD TO READER // CARD TO READER
if (!ReaderIsActive) { if (!ReaderIsActive) {
LED_C_INV();
// xor ( // LOW nibble is always tag data.
// if (sample & 0xF)
// tagbyte ^= (1 << (3 - div));
uint8_t tagdata = (previous_data << 4) | (*data & 0x0F); uint8_t tagdata = (previous_data << 4) | (*data & 0x0F);
if (ManchesterDecoding(tagdata)) { if (ManchesterDecoding(tagdata)) {
LED_C_INV(); time_stop = GetCountSspClk() - time_0;
time_stop = (GetCountSspClk() - time_0) << 4;
LogTrace(Demod.output, Demod.len, time_start, time_stop, NULL, false); LogTrace(Demod.output, Demod.len, time_start, time_stop, NULL, false);
// ready to receive another response.
DemodReset(); DemodReset();
// reset the Uart decode including its (now outdated) input buffer UartReset();
UartInit(readerToTagCmd);
} else { } else {
time_start = (GetCountSspClk() - time_0) << 4; time_start = GetCountSspClk() - time_0;
} }
div = 0;
//tagbyte = 00;
TagIsActive = (Demod.state != DEMOD_UNSYNCD); TagIsActive = (Demod.state != DEMOD_UNSYNCD);
} }
} }
previous_data = *data;
rsamples++;
data++;
if(data == dmaBuf + DMA_BUFFER_SIZE)
data = dmaBuf;
} // end main loop } // end main loop
if (MF_DBGLEVEL >= 1) { if (MF_DBGLEVEL >= 1) {
Dbprintf("maxDataLen=%x, Uart.state=%x, Uart.bytecn=%x", maxDataLen, Uart.state, Uart.byteCnt); DbpString("Sniff statistics:");
Dbprintf("tracelen=%x, Uart.output[0]=%x", BigBuf_get_traceLen(), (int)Uart.output[0]); Dbprintf(" maxDataLen=%x, Uart.state=%x, Uart.byteCnt=%x", maxDataLen, Uart.state, Uart.byteCnt);
Dbprintf(" Tracelen=%x, Uart.output[0]=%x", BigBuf_get_traceLen(), (int)Uart.output[0]);
Dbhexdump(datalen, data, false);
} }
switch_off(); switch_off();
} }

View file

@ -3087,7 +3087,7 @@ void RAMFUNC SniffMifare(uint8_t param) {
ReaderIsActive = false; ReaderIsActive = false;
TagIsActive = false; TagIsActive = false;
// Setup and start DMA. set transfer address and number of bytes. Start transfer. // Setup and start DMA. set transfer address and number of bytes. Start transfer.
if ( !FpgaSetupSscDma((uint8_t*) dmaBuf, DMA_BUFFER_SIZE) ){ if ( !FpgaSetupSscDma(dmaBuf, DMA_BUFFER_SIZE) ){
if (MF_DBGLEVEL > 1) Dbprintf("FpgaSetupSscDma failed. Exiting"); if (MF_DBGLEVEL > 1) Dbprintf("FpgaSetupSscDma failed. Exiting");
return; return;
} }

View file

@ -1546,12 +1546,10 @@ void RAMFUNC SnoopIso14443b(void) {
uint32_t time_0 = 0, time_start = 0, time_stop = 0; uint32_t time_0 = 0, time_start = 0, time_stop = 0;
int ci = 0, cq = 0; int ci = 0, cq = 0;
int lastRxCounter = ISO14443B_DMA_BUFFER_SIZE;
// We won't start recording the frames that we acquire until we trigger; // 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 // a good trigger condition to get started is probably when we see a
// response from the tag. // response from the tag.
bool triggered = true; // TODO: set and evaluate trigger condition
bool TagIsActive = false; bool TagIsActive = false;
bool ReaderIsActive = false; bool ReaderIsActive = false;
@ -1559,7 +1557,7 @@ void RAMFUNC SnoopIso14443b(void) {
// The DMA buffer, used to stream samples from the FPGA // The DMA buffer, used to stream samples from the FPGA
int8_t *dmaBuf = (int8_t*) BigBuf_malloc(ISO14443B_DMA_BUFFER_SIZE); int8_t *dmaBuf = (int8_t*) BigBuf_malloc(ISO14443B_DMA_BUFFER_SIZE);
int8_t *upTo = dmaBuf; int8_t *data = dmaBuf;
// Setup and start DMA. // Setup and start DMA.
if ( !FpgaSetupSscDma((uint8_t*) dmaBuf, ISO14443B_DMA_BUFFER_SIZE) ){ if ( !FpgaSetupSscDma((uint8_t*) dmaBuf, ISO14443B_DMA_BUFFER_SIZE) ){
@ -1568,73 +1566,46 @@ void RAMFUNC SnoopIso14443b(void) {
return; return;
} }
// time ZERO, the point from which it all is calculated.
time_0 = GetCountSspClk(); time_0 = GetCountSspClk();
// And now we loop, receiving samples. // loop and listen
for(;;) { while (!BUTTON_PRESS()) {
WDT_HIT(); WDT_HIT();
ci = upTo[0]; ci = data[0];
cq = upTo[1]; cq = data[1];
upTo += 2; data += 2;
lastRxCounter -= 2;
if (upTo >= dmaBuf + ISO14443B_DMA_BUFFER_SIZE) { if (data >= dmaBuf + ISO14443B_DMA_BUFFER_SIZE) {
upTo = dmaBuf; data = dmaBuf;
lastRxCounter = ISO14443B_DMA_BUFFER_SIZE;
AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dmaBuf; AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dmaBuf;
AT91C_BASE_PDC_SSC->PDC_RNCR = ISO14443B_DMA_BUFFER_SIZE; AT91C_BASE_PDC_SSC->PDC_RNCR = ISO14443B_DMA_BUFFER_SIZE;
if (!tracing) {
if (MF_DBGLEVEL >= 2) DbpString("Trace full");
break;
}
if (BUTTON_PRESS()) {
if (MF_DBGLEVEL >= 2) DbpString("cancelled");
break;
}
} }
if (!TagIsActive) { if (!TagIsActive) {
LED_A_ON(); LED_A_INV();
// no need to try decoding reader data if the tag is sending // no need to try decoding reader data if the tag is sending
if (Handle14443bReaderUartBit(ci & 0x01)) { if (Handle14443bReaderUartBit(ci & 0x01)) {
time_stop = GetCountSspClk() - time_0; time_stop = GetCountSspClk() - time_0;
if (triggered)
LogTrace(Uart.output, Uart.byteCnt, time_start, time_stop, NULL, true); LogTrace(Uart.output, Uart.byteCnt, time_start, time_stop, NULL, true);
/* And ready to receive another command. */
UartReset(); UartReset();
/* And also reset the demod code, which might have been */
/* false-triggered by the commands from the reader. */
DemodReset(); DemodReset();
} else { } else {
time_start = GetCountSspClk() - time_0; time_start = GetCountSspClk() - time_0;
} }
if (Handle14443bReaderUartBit(cq & 0x01)) { if (Handle14443bReaderUartBit(cq & 0x01)) {
time_stop = GetCountSspClk() - time_0; time_stop = GetCountSspClk() - time_0;
if (triggered)
LogTrace(Uart.output, Uart.byteCnt, time_start, time_stop, NULL, true); LogTrace(Uart.output, Uart.byteCnt, time_start, time_stop, NULL, true);
/* And ready to receive another command. */
UartReset(); UartReset();
/* And also reset the demod code, which might have been */
/* false-triggered by the commands from the reader. */
DemodReset(); DemodReset();
} else { } else {
time_start = GetCountSspClk() - time_0; time_start = GetCountSspClk() - time_0;
} }
ReaderIsActive = (Uart.state > STATE_GOT_FALLING_EDGE_OF_SOF); ReaderIsActive = (Uart.state > STATE_GOT_FALLING_EDGE_OF_SOF);
LED_A_OFF();
} }
if (!ReaderIsActive) { if (!ReaderIsActive) {
@ -1642,14 +1613,9 @@ void RAMFUNC SnoopIso14443b(void) {
// is this | 0x01 the error? & 0xfe in https://github.com/Proxmark/proxmark3/issues/103 // is this | 0x01 the error? & 0xfe in https://github.com/Proxmark/proxmark3/issues/103
// LSB is a fpga signal bit. // LSB is a fpga signal bit.
if (Handle14443bTagSamplesDemod(ci >> 1, cq >> 1)) { if (Handle14443bTagSamplesDemod(ci >> 1, cq >> 1)) {
time_stop = GetCountSspClk() - time_0; time_stop = GetCountSspClk() - time_0;
LogTrace(Demod.output, Demod.len, time_start, time_stop, NULL, false); LogTrace(Demod.output, Demod.len, time_start, time_stop, NULL, false);
UartReset();
triggered = true;
// And ready to receive another response.
DemodReset(); DemodReset();
} else { } else {
time_start = GetCountSspClk() - time_0; time_start = GetCountSspClk() - time_0;
@ -1658,17 +1624,13 @@ void RAMFUNC SnoopIso14443b(void) {
} }
} }
switch_off();
if (MF_DBGLEVEL >= 2) { if (MF_DBGLEVEL >= 2) {
DbpString("Snoop statistics:"); DbpString("Sniff statistics:");
Dbprintf(" Uart State: %x ByteCount: %i ByteCountMax: %i", Uart.state, Uart.byteCnt, Uart.byteCntMax); Dbprintf(" Uart State: %x ByteCount: %i ByteCountMax: %i", Uart.state, Uart.byteCnt, Uart.byteCntMax);
Dbprintf(" Trace length: %i", BigBuf_get_traceLen()); Dbprintf(" Trace length: %i", BigBuf_get_traceLen());
} }
// free mem refs.
if ( upTo ) upTo = NULL;
// Uart.byteCntMax should be set with ATQB value.. switch_off();
} }
void iso14b_set_trigger(bool enable) { void iso14b_set_trigger(bool enable) {

View file

@ -901,7 +901,6 @@ int CmdHF14AMfNested(const char *Cmd) {
uint64_t t2 = msclock() - t1; uint64_t t2 = msclock() - t1;
PrintAndLog("Time to check 6 known keys: %.0f seconds\n", (float)t2/1000.0 ); PrintAndLog("Time to check 6 known keys: %.0f seconds\n", (float)t2/1000.0 );
PrintAndLog("enter nested..."); PrintAndLog("enter nested...");
// nested sectors // nested sectors

View file

@ -71,7 +71,7 @@ static void showBanner(void){
printf("██╔═══╝ ██║╚██╔╝██║ ══█║ iceman@icesql.net\n"); printf("██╔═══╝ ██║╚██╔╝██║ ══█║ iceman@icesql.net\n");
printf("██║ ██║ ╚═╝ ██║ ████╔╝ https://github.com/iceman1001/proxmark3\n"); printf("██║ ██║ ╚═╝ ██║ ████╔╝ https://github.com/iceman1001/proxmark3\n");
printf("╚═╝ ╚═╝ ╚═╝ ╚═══╝v3.0.0\n"); printf("╚═╝ ╚═╝ ╚═╝ ╚═══╝v3.0.0\n");
printf("\nKeep icemanfork alive, donate to: https://paypal.me/iceman1001/"); printf("\nKeep icemanfork alive, do please donate, https://paypal.me/iceman1001/");
printf("\n\n"); printf("\n\n");
} }
#endif #endif