mirror of
https://github.com/Proxmark/proxmark3.git
synced 2025-08-19 12:59:44 -07:00
commit
24cbeb3d27
15 changed files with 1160 additions and 1144 deletions
137
armsrc/BigBuf.c
137
armsrc/BigBuf.c
|
@ -26,10 +26,9 @@ static uint16_t BigBuf_hi = BIGBUF_SIZE;
|
||||||
// pointer to the emulator memory.
|
// pointer to the emulator memory.
|
||||||
static uint8_t *emulator_memory = NULL;
|
static uint8_t *emulator_memory = NULL;
|
||||||
|
|
||||||
// trace related global variables
|
// trace related variables
|
||||||
// (only one left). ToDo: make this static as well?
|
static uint16_t traceLen = 0;
|
||||||
uint16_t traceLen = 0;
|
int tracing = 1; //Last global one.. todo static?
|
||||||
|
|
||||||
|
|
||||||
// get the address of BigBuf
|
// get the address of BigBuf
|
||||||
uint8_t *BigBuf_get_addr(void)
|
uint8_t *BigBuf_get_addr(void)
|
||||||
|
@ -95,3 +94,133 @@ uint16_t BigBuf_max_traceLen(void)
|
||||||
{
|
{
|
||||||
return BigBuf_hi;
|
return BigBuf_hi;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void clear_trace() {
|
||||||
|
uint8_t *trace = BigBuf_get_addr();
|
||||||
|
uint16_t max_traceLen = BigBuf_max_traceLen();
|
||||||
|
memset(trace, 0x44, max_traceLen);
|
||||||
|
traceLen = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_tracing(bool enable) {
|
||||||
|
tracing = enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the number of bytes traced
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
uint16_t BigBuf_get_traceLen(void)
|
||||||
|
{
|
||||||
|
return traceLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
This is a function to store traces. All protocols can use this generic tracer-function.
|
||||||
|
The traces produced by calling this function can be fetched on the client-side
|
||||||
|
by 'hf list raw', alternatively 'hf list <proto>' for protocol-specific
|
||||||
|
annotation of commands/responses.
|
||||||
|
|
||||||
|
**/
|
||||||
|
bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag)
|
||||||
|
{
|
||||||
|
if (!tracing) return FALSE;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
// Return when trace is full
|
||||||
|
uint16_t max_traceLen = BigBuf_max_traceLen();
|
||||||
|
|
||||||
|
if (traceLen + sizeof(iLen) + sizeof(timestamp_start) + sizeof(duration) + num_paritybytes + iLen >= max_traceLen) {
|
||||||
|
tracing = FALSE; // don't trace any more
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
// Traceformat:
|
||||||
|
// 32 bits timestamp (little endian)
|
||||||
|
// 16 bits duration (little endian)
|
||||||
|
// 16 bits data length (little endian, Highest Bit used as readerToTag flag)
|
||||||
|
// y Bytes data
|
||||||
|
// x Bytes parity (one byte per 8 bytes data)
|
||||||
|
|
||||||
|
// timestamp (start)
|
||||||
|
trace[traceLen++] = ((timestamp_start >> 0) & 0xff);
|
||||||
|
trace[traceLen++] = ((timestamp_start >> 8) & 0xff);
|
||||||
|
trace[traceLen++] = ((timestamp_start >> 16) & 0xff);
|
||||||
|
trace[traceLen++] = ((timestamp_start >> 24) & 0xff);
|
||||||
|
|
||||||
|
// duration
|
||||||
|
trace[traceLen++] = ((duration >> 0) & 0xff);
|
||||||
|
trace[traceLen++] = ((duration >> 8) & 0xff);
|
||||||
|
|
||||||
|
// data length
|
||||||
|
trace[traceLen++] = ((iLen >> 0) & 0xff);
|
||||||
|
trace[traceLen++] = ((iLen >> 8) & 0xff);
|
||||||
|
|
||||||
|
// readerToTag flag
|
||||||
|
if (!readerToTag) {
|
||||||
|
trace[traceLen - 1] |= 0x80;
|
||||||
|
}
|
||||||
|
|
||||||
|
// data bytes
|
||||||
|
if (btBytes != NULL && iLen != 0) {
|
||||||
|
memcpy(trace + traceLen, btBytes, iLen);
|
||||||
|
}
|
||||||
|
traceLen += iLen;
|
||||||
|
|
||||||
|
// parity bytes
|
||||||
|
if (parity != NULL && iLen != 0) {
|
||||||
|
memcpy(trace + traceLen, parity, num_paritybytes);
|
||||||
|
}
|
||||||
|
traceLen += num_paritybytes;
|
||||||
|
|
||||||
|
if(traceLen +4 < max_traceLen)
|
||||||
|
{ //If it hadn't been cleared, for whatever reason..
|
||||||
|
memset(trace+traceLen,0x44, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
int LogTraceHitag(const uint8_t * btBytes, int iBits, int iSamples, uint32_t dwParity, int readerToTag)
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
Todo, rewrite the logger to use the generic functionality instead. It should be noted, however,
|
||||||
|
that this logger takes number of bits as argument, not number of bytes.
|
||||||
|
**/
|
||||||
|
|
||||||
|
if (!tracing) return FALSE;
|
||||||
|
|
||||||
|
uint8_t *trace = BigBuf_get_addr();
|
||||||
|
uint16_t iLen = nbytes(iBits);
|
||||||
|
// Return when trace is full
|
||||||
|
if (traceLen + sizeof(rsamples) + sizeof(dwParity) + sizeof(iBits) + iLen > BigBuf_max_traceLen()) return FALSE;
|
||||||
|
|
||||||
|
//Hitag traces appear to use this traceformat:
|
||||||
|
// 32 bits timestamp (little endian,Highest Bit used as readerToTag flag)
|
||||||
|
// 32 bits parity
|
||||||
|
// 8 bits size (number of bits in the trace entry, not number of bytes)
|
||||||
|
// y Bytes data
|
||||||
|
|
||||||
|
rsamples += iSamples;
|
||||||
|
trace[traceLen++] = ((rsamples >> 0) & 0xff);
|
||||||
|
trace[traceLen++] = ((rsamples >> 8) & 0xff);
|
||||||
|
trace[traceLen++] = ((rsamples >> 16) & 0xff);
|
||||||
|
trace[traceLen++] = ((rsamples >> 24) & 0xff);
|
||||||
|
|
||||||
|
if (!readerToTag) {
|
||||||
|
trace[traceLen - 1] |= 0x80;
|
||||||
|
}
|
||||||
|
|
||||||
|
trace[traceLen++] = ((dwParity >> 0) & 0xff);
|
||||||
|
trace[traceLen++] = ((dwParity >> 8) & 0xff);
|
||||||
|
trace[traceLen++] = ((dwParity >> 16) & 0xff);
|
||||||
|
trace[traceLen++] = ((dwParity >> 24) & 0xff);
|
||||||
|
trace[traceLen++] = iBits;
|
||||||
|
|
||||||
|
memcpy(trace + traceLen, btBytes, iLen);
|
||||||
|
traceLen += iLen;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
|
@ -29,6 +29,9 @@ extern uint8_t *BigBuf_malloc(uint16_t);
|
||||||
extern void BigBuf_free(void);
|
extern void BigBuf_free(void);
|
||||||
extern void BigBuf_free_keep_EM(void);
|
extern void BigBuf_free_keep_EM(void);
|
||||||
|
|
||||||
extern uint16_t traceLen;
|
uint16_t BigBuf_get_traceLen(void);
|
||||||
|
void clear_trace();
|
||||||
|
void set_tracing(bool enable);
|
||||||
|
bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag);
|
||||||
|
int LogTraceHitag(const uint8_t * btBytes, int iBits, int iSamples, uint32_t dwParity, int bReader);
|
||||||
#endif /* __BIGBUF_H */
|
#endif /* __BIGBUF_H */
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "legicrf.h"
|
#include "legicrf.h"
|
||||||
#include <hitag2.h>
|
#include <hitag2.h>
|
||||||
#include "lfsampling.h"
|
#include "lfsampling.h"
|
||||||
|
#include "BigBuf.h"
|
||||||
#ifdef WITH_LCD
|
#ifdef WITH_LCD
|
||||||
#include "LCD.h"
|
#include "LCD.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -933,10 +934,10 @@ void UsbPacketReceived(uint8_t *packet, int len)
|
||||||
uint8_t *BigBuf = BigBuf_get_addr();
|
uint8_t *BigBuf = BigBuf_get_addr();
|
||||||
for(size_t i=0; i<c->arg[1]; i += USB_CMD_DATA_SIZE) {
|
for(size_t i=0; i<c->arg[1]; i += USB_CMD_DATA_SIZE) {
|
||||||
size_t len = MIN((c->arg[1] - i),USB_CMD_DATA_SIZE);
|
size_t len = MIN((c->arg[1] - i),USB_CMD_DATA_SIZE);
|
||||||
cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K,i,len,traceLen,BigBuf+c->arg[0]+i,len);
|
cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K,i,len,BigBuf_get_traceLen(),BigBuf+c->arg[0]+i,len);
|
||||||
}
|
}
|
||||||
// Trigger a finish downloading signal with an ACK frame
|
// Trigger a finish downloading signal with an ACK frame
|
||||||
cmd_send(CMD_ACK,1,0,traceLen,getSamplingConfig(),sizeof(sample_config));
|
cmd_send(CMD_ACK,1,0,BigBuf_get_traceLen(),getSamplingConfig(),sizeof(sample_config));
|
||||||
LED_B_OFF();
|
LED_B_OFF();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1012,7 +1013,7 @@ void UsbPacketReceived(uint8_t *packet, int len)
|
||||||
void __attribute__((noreturn)) AppMain(void)
|
void __attribute__((noreturn)) AppMain(void)
|
||||||
{
|
{
|
||||||
SpinDelay(100);
|
SpinDelay(100);
|
||||||
|
clear_trace();
|
||||||
if(common_area.magic != COMMON_AREA_MAGIC || common_area.version != 1) {
|
if(common_area.magic != COMMON_AREA_MAGIC || common_area.version != 1) {
|
||||||
/* Initialize common area */
|
/* Initialize common area */
|
||||||
memset(&common_area, 0, sizeof(common_area));
|
memset(&common_area, 0, sizeof(common_area));
|
||||||
|
|
|
@ -152,8 +152,7 @@ void ReaderIso14443a(UsbCommand * c);
|
||||||
bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t len, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag);
|
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 GetParity(const uint8_t *pbtCmd, uint16_t len, uint8_t *parity);
|
||||||
void iso14a_set_trigger(bool enable);
|
void iso14a_set_trigger(bool enable);
|
||||||
void iso14a_clear_trace();
|
|
||||||
void iso14a_set_tracing(bool enable);
|
|
||||||
void RAMFUNC SniffMifare(uint8_t param);
|
void RAMFUNC SniffMifare(uint8_t param);
|
||||||
|
|
||||||
/// epa.h
|
/// epa.h
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "hitag2.h"
|
#include "hitag2.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
|
#include "BigBuf.h"
|
||||||
|
|
||||||
static bool bQuiet;
|
static bool bQuiet;
|
||||||
|
|
||||||
|
@ -30,32 +31,6 @@ static bool bPwd;
|
||||||
static bool bSuccessful;
|
static bool bSuccessful;
|
||||||
|
|
||||||
|
|
||||||
static int LogTraceHitag(const uint8_t * btBytes, int iBits, int iSamples, uint32_t dwParity, int bReader)
|
|
||||||
{
|
|
||||||
static uint16_t traceLen = 0;
|
|
||||||
uint8_t *trace = BigBuf_get_addr();
|
|
||||||
|
|
||||||
// Return when trace is full
|
|
||||||
if (traceLen + sizeof(rsamples) + sizeof(dwParity) + sizeof(iBits) + nbytes(iBits) > BigBuf_max_traceLen()) return FALSE;
|
|
||||||
|
|
||||||
// Trace the random, i'm curious
|
|
||||||
rsamples += iSamples;
|
|
||||||
trace[traceLen++] = ((rsamples >> 0) & 0xff);
|
|
||||||
trace[traceLen++] = ((rsamples >> 8) & 0xff);
|
|
||||||
trace[traceLen++] = ((rsamples >> 16) & 0xff);
|
|
||||||
trace[traceLen++] = ((rsamples >> 24) & 0xff);
|
|
||||||
if (!bReader) {
|
|
||||||
trace[traceLen - 1] |= 0x80;
|
|
||||||
}
|
|
||||||
trace[traceLen++] = ((dwParity >> 0) & 0xff);
|
|
||||||
trace[traceLen++] = ((dwParity >> 8) & 0xff);
|
|
||||||
trace[traceLen++] = ((dwParity >> 16) & 0xff);
|
|
||||||
trace[traceLen++] = ((dwParity >> 24) & 0xff);
|
|
||||||
trace[traceLen++] = iBits;
|
|
||||||
memcpy(trace + traceLen, btBytes, nbytes(iBits));
|
|
||||||
traceLen += nbytes(iBits);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct hitag2_tag {
|
struct hitag2_tag {
|
||||||
uint32_t uid;
|
uint32_t uid;
|
||||||
|
@ -742,8 +717,8 @@ void SnoopHitag(uint32_t type) {
|
||||||
memset(auth_table, 0x00, AUTH_TABLE_LENGTH);
|
memset(auth_table, 0x00, AUTH_TABLE_LENGTH);
|
||||||
|
|
||||||
// Clean up trace and prepare it for storing frames
|
// Clean up trace and prepare it for storing frames
|
||||||
iso14a_set_tracing(TRUE);
|
set_tracing(TRUE);
|
||||||
iso14a_clear_trace();
|
clear_trace();
|
||||||
|
|
||||||
DbpString("Starting Hitag2 snoop");
|
DbpString("Starting Hitag2 snoop");
|
||||||
LED_D_ON();
|
LED_D_ON();
|
||||||
|
@ -955,8 +930,8 @@ void SimulateHitagTag(bool tag_mem_supplied, byte_t* data) {
|
||||||
memset(auth_table, 0x00, AUTH_TABLE_LENGTH);
|
memset(auth_table, 0x00, AUTH_TABLE_LENGTH);
|
||||||
|
|
||||||
// Clean up trace and prepare it for storing frames
|
// Clean up trace and prepare it for storing frames
|
||||||
iso14a_set_tracing(TRUE);
|
set_tracing(TRUE);
|
||||||
iso14a_clear_trace();
|
clear_trace();
|
||||||
|
|
||||||
DbpString("Starting Hitag2 simulation");
|
DbpString("Starting Hitag2 simulation");
|
||||||
LED_D_ON();
|
LED_D_ON();
|
||||||
|
@ -1142,8 +1117,8 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
|
||||||
bSuccessful = false;
|
bSuccessful = false;
|
||||||
|
|
||||||
// Clean up trace and prepare it for storing frames
|
// Clean up trace and prepare it for storing frames
|
||||||
iso14a_set_tracing(TRUE);
|
set_tracing(TRUE);
|
||||||
iso14a_clear_trace();
|
clear_trace();
|
||||||
|
|
||||||
DbpString("Starting Hitag reader family");
|
DbpString("Starting Hitag reader family");
|
||||||
|
|
||||||
|
|
|
@ -652,9 +652,8 @@ void RAMFUNC SnoopIClass(void)
|
||||||
// The DMA buffer, used to stream samples from the FPGA
|
// The DMA buffer, used to stream samples from the FPGA
|
||||||
uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE);
|
uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE);
|
||||||
|
|
||||||
// reset traceLen to 0
|
set_tracing(TRUE);
|
||||||
iso14a_set_tracing(TRUE);
|
clear_trace();
|
||||||
iso14a_clear_trace();
|
|
||||||
iso14a_set_trigger(FALSE);
|
iso14a_set_trigger(FALSE);
|
||||||
|
|
||||||
int lastRxCounter;
|
int lastRxCounter;
|
||||||
|
@ -805,12 +804,12 @@ void RAMFUNC SnoopIClass(void)
|
||||||
DbpString("COMMAND FINISHED");
|
DbpString("COMMAND FINISHED");
|
||||||
|
|
||||||
Dbprintf("%x %x %x", maxBehindBy, Uart.state, Uart.byteCnt);
|
Dbprintf("%x %x %x", maxBehindBy, Uart.state, Uart.byteCnt);
|
||||||
Dbprintf("%x %x %x", Uart.byteCntMax, traceLen, (int)Uart.output[0]);
|
Dbprintf("%x %x %x", Uart.byteCntMax, BigBuf_get_traceLen(), (int)Uart.output[0]);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
|
AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
|
||||||
Dbprintf("%x %x %x", maxBehindBy, Uart.state, Uart.byteCnt);
|
Dbprintf("%x %x %x", maxBehindBy, Uart.state, Uart.byteCnt);
|
||||||
Dbprintf("%x %x %x", Uart.byteCntMax, traceLen, (int)Uart.output[0]);
|
Dbprintf("%x %x %x", Uart.byteCntMax, BigBuf_get_traceLen(), (int)Uart.output[0]);
|
||||||
LED_A_OFF();
|
LED_A_OFF();
|
||||||
LED_B_OFF();
|
LED_B_OFF();
|
||||||
LED_C_OFF();
|
LED_C_OFF();
|
||||||
|
@ -987,8 +986,8 @@ void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain
|
||||||
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
||||||
|
|
||||||
// Enable and clear the trace
|
// Enable and clear the trace
|
||||||
iso14a_set_tracing(TRUE);
|
set_tracing(TRUE);
|
||||||
iso14a_clear_trace();
|
clear_trace();
|
||||||
|
|
||||||
uint8_t csn_crc[] = { 0x03, 0x1f, 0xec, 0x8a, 0xf7, 0xff, 0x12, 0xe0, 0x00, 0x00 };
|
uint8_t csn_crc[] = { 0x03, 0x1f, 0xec, 0x8a, 0xf7, 0xff, 0x12, 0xe0, 0x00, 0x00 };
|
||||||
if(simType == 0) {
|
if(simType == 0) {
|
||||||
|
@ -1488,8 +1487,8 @@ void setupIclassReader()
|
||||||
{
|
{
|
||||||
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
||||||
// Reset trace buffer
|
// Reset trace buffer
|
||||||
iso14a_set_tracing(TRUE);
|
set_tracing(TRUE);
|
||||||
iso14a_clear_trace();
|
clear_trace();
|
||||||
|
|
||||||
// Setup SSC
|
// Setup SSC
|
||||||
FpgaSetupSsc();
|
FpgaSetupSsc();
|
||||||
|
@ -1585,14 +1584,14 @@ void ReaderIClass(uint8_t arg0) {
|
||||||
int read_status= 0;
|
int read_status= 0;
|
||||||
bool abort_after_read = arg0 & FLAG_ICLASS_READER_ONLY_ONCE;
|
bool abort_after_read = arg0 & FLAG_ICLASS_READER_ONLY_ONCE;
|
||||||
bool get_cc = arg0 & FLAG_ICLASS_READER_GET_CC;
|
bool get_cc = arg0 & FLAG_ICLASS_READER_GET_CC;
|
||||||
|
set_tracing(TRUE);
|
||||||
setupIclassReader();
|
setupIclassReader();
|
||||||
|
|
||||||
size_t datasize = 0;
|
size_t datasize = 0;
|
||||||
while(!BUTTON_PRESS())
|
while(!BUTTON_PRESS())
|
||||||
{
|
{
|
||||||
|
|
||||||
if(traceLen > BigBuf_max_traceLen()) {
|
if(!tracing) {
|
||||||
DbpString("Trace full");
|
DbpString("Trace full");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1658,13 +1657,13 @@ void ReaderIClass_Replay(uint8_t arg0, uint8_t *MAC) {
|
||||||
uint8_t resp[ICLASS_BUFFER_SIZE];
|
uint8_t resp[ICLASS_BUFFER_SIZE];
|
||||||
|
|
||||||
setupIclassReader();
|
setupIclassReader();
|
||||||
|
set_tracing(TRUE);
|
||||||
|
|
||||||
while(!BUTTON_PRESS()) {
|
while(!BUTTON_PRESS()) {
|
||||||
|
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
|
|
||||||
if(traceLen > BigBuf_max_traceLen()) {
|
if(!tracing) {
|
||||||
DbpString("Trace full");
|
DbpString("Trace full");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,11 +19,11 @@
|
||||||
|
|
||||||
//static void GetSamplesFor14443(int weTx, int n);
|
//static void GetSamplesFor14443(int weTx, int n);
|
||||||
|
|
||||||
#define DEMOD_TRACE_SIZE 4096
|
/*#define DEMOD_TRACE_SIZE 4096
|
||||||
#define READER_TAG_BUFFER_SIZE 2048
|
#define READER_TAG_BUFFER_SIZE 2048
|
||||||
#define TAG_READER_BUFFER_SIZE 2048
|
#define TAG_READER_BUFFER_SIZE 2048
|
||||||
#define DEMOD_DMA_BUFFER_SIZE 1024
|
#define DEMOD_DMA_BUFFER_SIZE 1024
|
||||||
|
*/
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
// An ISO 14443 Type B tag. We listen for commands from the reader, using
|
// An ISO 14443 Type B tag. We listen for commands from the reader, using
|
||||||
// a UART kind of thing that's implemented in software. When we get a
|
// a UART kind of thing that's implemented in software. When we get a
|
||||||
|
@ -616,9 +616,34 @@ static RAMFUNC int Handle14443SamplesDemod(int ci, int cq)
|
||||||
if (Demod.state == DEMOD_UNSYNCD) LED_C_OFF(); // Not synchronized...
|
if (Demod.state == DEMOD_UNSYNCD) LED_C_OFF(); // Not synchronized...
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
static void DemodReset()
|
||||||
|
{
|
||||||
|
// Clear out the state of the "UART" that receives from the tag.
|
||||||
|
Demod.len = 0;
|
||||||
|
Demod.state = DEMOD_UNSYNCD;
|
||||||
|
memset(Demod.output, 0x00, MAX_FRAME_SIZE);
|
||||||
|
}
|
||||||
|
static void DemodInit(uint8_t *data)
|
||||||
|
{
|
||||||
|
Demod.output = data;
|
||||||
|
DemodReset();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void UartReset()
|
||||||
|
{
|
||||||
|
Uart.byteCntMax = MAX_FRAME_SIZE;
|
||||||
|
Uart.state = STATE_UNSYNCD;
|
||||||
|
Uart.byteCnt = 0;
|
||||||
|
Uart.bitCnt = 0;
|
||||||
|
}
|
||||||
|
static void UartInit(uint8_t *data)
|
||||||
|
{
|
||||||
|
Uart.output = data;
|
||||||
|
UartReset();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Demodulate the samples we received from the tag
|
* Demodulate the samples we received from the tag, also log to tracebuffer
|
||||||
* weTx: set to 'TRUE' if we behave like a reader
|
* weTx: set to 'TRUE' if we behave like a reader
|
||||||
* set to 'FALSE' if we behave like a snooper
|
* set to 'FALSE' if we behave like a snooper
|
||||||
* quiet: set to 'TRUE' to disable debug output
|
* quiet: set to 'TRUE' to disable debug output
|
||||||
|
@ -627,34 +652,31 @@ static void GetSamplesFor14443Demod(int weTx, int n, int quiet)
|
||||||
{
|
{
|
||||||
int max = 0;
|
int max = 0;
|
||||||
int gotFrame = FALSE;
|
int gotFrame = FALSE;
|
||||||
|
int lastRxCounter, ci, cq, samples = 0;
|
||||||
|
|
||||||
//# define DMA_BUFFER_SIZE 8
|
// Allocate memory from BigBuf for some buffers
|
||||||
uint8_t *dmaBuf;
|
// free all previous allocations first
|
||||||
|
BigBuf_free();
|
||||||
|
|
||||||
int lastRxCounter;
|
// The command (reader -> tag) that we're receiving.
|
||||||
uint8_t *upTo;
|
uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE);
|
||||||
|
|
||||||
int ci, cq;
|
// The response (tag -> reader) that we're receiving.
|
||||||
|
uint8_t *receivedResponse = BigBuf_malloc(MAX_FRAME_SIZE);
|
||||||
|
|
||||||
int samples = 0;
|
// The DMA buffer, used to stream samples from the FPGA
|
||||||
|
uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE);
|
||||||
|
|
||||||
// Clear out the state of the "UART" that receives from the tag.
|
// Set up the demodulator for tag -> reader responses.
|
||||||
uint8_t *BigBuf = BigBuf_get_addr();
|
DemodInit(receivedResponse);
|
||||||
memset(BigBuf, 0x00, 400);
|
// Set up the demodulator for the reader -> tag commands
|
||||||
Demod.output = BigBuf;
|
UartInit(receivedCmd);
|
||||||
Demod.len = 0;
|
|
||||||
Demod.state = DEMOD_UNSYNCD;
|
|
||||||
|
|
||||||
// And the UART that receives from the reader
|
// Setup and start DMA.
|
||||||
Uart.output = BigBuf + 1024;
|
FpgaSetupSscDma(dmaBuf, DMA_BUFFER_SIZE);
|
||||||
Uart.byteCntMax = 100;
|
|
||||||
Uart.state = STATE_UNSYNCD;
|
|
||||||
|
|
||||||
// Setup for the DMA.
|
uint8_t *upTo= dmaBuf;
|
||||||
dmaBuf = BigBuf + 32;
|
lastRxCounter = DMA_BUFFER_SIZE;
|
||||||
upTo = dmaBuf;
|
|
||||||
lastRxCounter = DEMOD_DMA_BUFFER_SIZE;
|
|
||||||
FpgaSetupSscDma(dmaBuf, DEMOD_DMA_BUFFER_SIZE);
|
|
||||||
|
|
||||||
// Signal field is ON with the appropriate LED:
|
// Signal field is ON with the appropriate LED:
|
||||||
if (weTx) LED_D_ON(); else LED_D_OFF();
|
if (weTx) LED_D_ON(); else LED_D_OFF();
|
||||||
|
@ -667,20 +689,20 @@ static void GetSamplesFor14443Demod(int weTx, int n, int quiet)
|
||||||
int behindBy = lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR;
|
int behindBy = lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR;
|
||||||
if(behindBy > max) max = behindBy;
|
if(behindBy > max) max = behindBy;
|
||||||
|
|
||||||
while(((lastRxCounter-AT91C_BASE_PDC_SSC->PDC_RCR) & (DEMOD_DMA_BUFFER_SIZE-1))
|
while(((lastRxCounter-AT91C_BASE_PDC_SSC->PDC_RCR) & (DMA_BUFFER_SIZE-1))
|
||||||
> 2)
|
> 2)
|
||||||
{
|
{
|
||||||
ci = upTo[0];
|
ci = upTo[0];
|
||||||
cq = upTo[1];
|
cq = upTo[1];
|
||||||
upTo += 2;
|
upTo += 2;
|
||||||
if(upTo - dmaBuf > DEMOD_DMA_BUFFER_SIZE) {
|
if(upTo - dmaBuf > DMA_BUFFER_SIZE) {
|
||||||
upTo -= DEMOD_DMA_BUFFER_SIZE;
|
upTo -= DMA_BUFFER_SIZE;
|
||||||
AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) upTo;
|
AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) upTo;
|
||||||
AT91C_BASE_PDC_SSC->PDC_RNCR = DEMOD_DMA_BUFFER_SIZE;
|
AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE;
|
||||||
}
|
}
|
||||||
lastRxCounter -= 2;
|
lastRxCounter -= 2;
|
||||||
if(lastRxCounter <= 0) {
|
if(lastRxCounter <= 0) {
|
||||||
lastRxCounter += DEMOD_DMA_BUFFER_SIZE;
|
lastRxCounter += DMA_BUFFER_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
samples += 2;
|
samples += 2;
|
||||||
|
@ -699,6 +721,12 @@ static void GetSamplesFor14443Demod(int weTx, int n, int quiet)
|
||||||
}
|
}
|
||||||
AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
|
AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
|
||||||
if (!quiet) Dbprintf("%x %x %x", max, gotFrame, Demod.len);
|
if (!quiet) Dbprintf("%x %x %x", max, gotFrame, Demod.len);
|
||||||
|
//Tracing
|
||||||
|
if (tracing && Demod.len > 0) {
|
||||||
|
uint8_t parity[MAX_PARITY_SIZE];
|
||||||
|
GetParity(Demod.output , Demod.len, parity);
|
||||||
|
LogTrace(Demod.output,Demod.len, 0, 0, parity, FALSE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -854,6 +882,20 @@ void AcquireRawAdcSamplesIso14443(uint32_t parameter)
|
||||||
SendRawCommand14443B(sizeof(cmd1),1,1,cmd1);
|
SendRawCommand14443B(sizeof(cmd1),1,1,cmd1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Convenience function to encode, transmit and trace iso 14443b comms
|
||||||
|
**/
|
||||||
|
static void CodeAndTransmit14443bAsReader(const uint8_t *cmd, int len)
|
||||||
|
{
|
||||||
|
CodeIso14443bAsReader(cmd, len);
|
||||||
|
TransmitFor14443();
|
||||||
|
if (tracing) {
|
||||||
|
uint8_t parity[MAX_PARITY_SIZE];
|
||||||
|
GetParity(cmd, len, parity);
|
||||||
|
LogTrace(cmd,len, 0, 0, parity, TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Read a SRI512 ISO 14443 tag.
|
// Read a SRI512 ISO 14443 tag.
|
||||||
//
|
//
|
||||||
|
@ -865,6 +907,9 @@ void AcquireRawAdcSamplesIso14443(uint32_t parameter)
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void ReadSTMemoryIso14443(uint32_t dwLast)
|
void ReadSTMemoryIso14443(uint32_t dwLast)
|
||||||
{
|
{
|
||||||
|
clear_trace();
|
||||||
|
set_tracing(TRUE);
|
||||||
|
|
||||||
uint8_t i = 0x00;
|
uint8_t i = 0x00;
|
||||||
|
|
||||||
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
||||||
|
@ -886,8 +931,8 @@ void ReadSTMemoryIso14443(uint32_t dwLast)
|
||||||
|
|
||||||
// First command: wake up the tag using the INITIATE command
|
// First command: wake up the tag using the INITIATE command
|
||||||
uint8_t cmd1[] = { 0x06, 0x00, 0x97, 0x5b};
|
uint8_t cmd1[] = { 0x06, 0x00, 0x97, 0x5b};
|
||||||
CodeIso14443bAsReader(cmd1, sizeof(cmd1));
|
|
||||||
TransmitFor14443();
|
CodeAndTransmit14443bAsReader(cmd1, sizeof(cmd1));
|
||||||
// LED_A_ON();
|
// LED_A_ON();
|
||||||
GetSamplesFor14443Demod(TRUE, 2000,TRUE);
|
GetSamplesFor14443Demod(TRUE, 2000,TRUE);
|
||||||
// LED_A_OFF();
|
// LED_A_OFF();
|
||||||
|
@ -904,8 +949,8 @@ void ReadSTMemoryIso14443(uint32_t dwLast)
|
||||||
cmd1[0] = 0x0E; // 0x0E is SELECT
|
cmd1[0] = 0x0E; // 0x0E is SELECT
|
||||||
cmd1[1] = Demod.output[0];
|
cmd1[1] = Demod.output[0];
|
||||||
ComputeCrc14443(CRC_14443_B, cmd1, 2, &cmd1[2], &cmd1[3]);
|
ComputeCrc14443(CRC_14443_B, cmd1, 2, &cmd1[2], &cmd1[3]);
|
||||||
CodeIso14443bAsReader(cmd1, sizeof(cmd1));
|
CodeAndTransmit14443bAsReader(cmd1, sizeof(cmd1));
|
||||||
TransmitFor14443();
|
|
||||||
// LED_A_ON();
|
// LED_A_ON();
|
||||||
GetSamplesFor14443Demod(TRUE, 2000,TRUE);
|
GetSamplesFor14443Demod(TRUE, 2000,TRUE);
|
||||||
// LED_A_OFF();
|
// LED_A_OFF();
|
||||||
|
@ -928,8 +973,8 @@ void ReadSTMemoryIso14443(uint32_t dwLast)
|
||||||
// First get the tag's UID:
|
// First get the tag's UID:
|
||||||
cmd1[0] = 0x0B;
|
cmd1[0] = 0x0B;
|
||||||
ComputeCrc14443(CRC_14443_B, cmd1, 1 , &cmd1[1], &cmd1[2]);
|
ComputeCrc14443(CRC_14443_B, cmd1, 1 , &cmd1[1], &cmd1[2]);
|
||||||
CodeIso14443bAsReader(cmd1, 3); // Only first three bytes for this one
|
CodeAndTransmit14443bAsReader(cmd1, 3); // Only first three bytes for this one
|
||||||
TransmitFor14443();
|
|
||||||
// LED_A_ON();
|
// LED_A_ON();
|
||||||
GetSamplesFor14443Demod(TRUE, 2000,TRUE);
|
GetSamplesFor14443Demod(TRUE, 2000,TRUE);
|
||||||
// LED_A_OFF();
|
// LED_A_OFF();
|
||||||
|
@ -960,8 +1005,8 @@ void ReadSTMemoryIso14443(uint32_t dwLast)
|
||||||
}
|
}
|
||||||
cmd1[1] = i;
|
cmd1[1] = i;
|
||||||
ComputeCrc14443(CRC_14443_B, cmd1, 2, &cmd1[2], &cmd1[3]);
|
ComputeCrc14443(CRC_14443_B, cmd1, 2, &cmd1[2], &cmd1[3]);
|
||||||
CodeIso14443bAsReader(cmd1, sizeof(cmd1));
|
CodeAndTransmit14443bAsReader(cmd1, sizeof(cmd1));
|
||||||
TransmitFor14443();
|
|
||||||
// LED_A_ON();
|
// LED_A_ON();
|
||||||
GetSamplesFor14443Demod(TRUE, 2000,TRUE);
|
GetSamplesFor14443Demod(TRUE, 2000,TRUE);
|
||||||
// LED_A_OFF();
|
// LED_A_OFF();
|
||||||
|
@ -1014,18 +1059,12 @@ void RAMFUNC SnoopIso14443(void)
|
||||||
|
|
||||||
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
||||||
BigBuf_free();
|
BigBuf_free();
|
||||||
// The command (reader -> tag) that we're working on receiving.
|
|
||||||
uint8_t *receivedCmd = BigBuf_malloc(READER_TAG_BUFFER_SIZE);
|
|
||||||
// The response (tag -> reader) that we're working on receiving.
|
|
||||||
uint8_t *receivedResponse = BigBuf_malloc(TAG_READER_BUFFER_SIZE);
|
|
||||||
|
|
||||||
// As we receive stuff, we copy it from receivedCmd or receivedResponse
|
clear_trace();
|
||||||
// into trace, along with its length and other annotations.
|
set_tracing(TRUE);
|
||||||
uint8_t *trace = BigBuf_get_addr();
|
|
||||||
traceLen = 0;
|
|
||||||
|
|
||||||
// The DMA buffer, used to stream samples from the FPGA.
|
// The DMA buffer, used to stream samples from the FPGA
|
||||||
uint8_t *dmaBuf = BigBuf_malloc(DEMOD_DMA_BUFFER_SIZE);
|
uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE);
|
||||||
int lastRxCounter;
|
int lastRxCounter;
|
||||||
uint8_t *upTo;
|
uint8_t *upTo;
|
||||||
int ci, cq;
|
int ci, cq;
|
||||||
|
@ -1035,30 +1074,20 @@ void RAMFUNC SnoopIso14443(void)
|
||||||
// information in the trace buffer.
|
// information in the trace buffer.
|
||||||
int samples = 0;
|
int samples = 0;
|
||||||
|
|
||||||
// Initialize the trace buffer
|
DemodInit(BigBuf_malloc(MAX_FRAME_SIZE));
|
||||||
memset(trace, 0x44, BigBuf_max_traceLen());
|
UartInit(BigBuf_malloc(MAX_FRAME_SIZE));
|
||||||
|
|
||||||
// Set up the demodulator for tag -> reader responses.
|
|
||||||
Demod.output = receivedResponse;
|
|
||||||
Demod.len = 0;
|
|
||||||
Demod.state = DEMOD_UNSYNCD;
|
|
||||||
|
|
||||||
// And the reader -> tag commands
|
|
||||||
memset(&Uart, 0, sizeof(Uart));
|
|
||||||
Uart.output = receivedCmd;
|
|
||||||
Uart.byteCntMax = 100;
|
|
||||||
Uart.state = STATE_UNSYNCD;
|
|
||||||
|
|
||||||
// Print some debug information about the buffer sizes
|
// Print some debug information about the buffer sizes
|
||||||
Dbprintf("Snooping buffers initialized:");
|
Dbprintf("Snooping buffers initialized:");
|
||||||
Dbprintf(" Trace: %i bytes", BigBuf_max_traceLen());
|
Dbprintf(" Trace: %i bytes", BigBuf_max_traceLen());
|
||||||
Dbprintf(" Reader -> tag: %i bytes", READER_TAG_BUFFER_SIZE);
|
Dbprintf(" Reader -> tag: %i bytes", MAX_FRAME_SIZE);
|
||||||
Dbprintf(" tag -> Reader: %i bytes", TAG_READER_BUFFER_SIZE);
|
Dbprintf(" tag -> Reader: %i bytes", MAX_FRAME_SIZE);
|
||||||
Dbprintf(" DMA: %i bytes", DEMOD_DMA_BUFFER_SIZE);
|
Dbprintf(" DMA: %i bytes", DMA_BUFFER_SIZE);
|
||||||
|
|
||||||
// And put the FPGA in the appropriate mode
|
|
||||||
// Signal field is off with the appropriate LED
|
// Signal field is off with the appropriate LED
|
||||||
LED_D_OFF();
|
LED_D_OFF();
|
||||||
|
|
||||||
|
// And put the FPGA in the appropriate mode
|
||||||
FpgaWriteConfWord(
|
FpgaWriteConfWord(
|
||||||
FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ |
|
FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ |
|
||||||
FPGA_HF_READER_RX_XCORR_SNOOP);
|
FPGA_HF_READER_RX_XCORR_SNOOP);
|
||||||
|
@ -1067,20 +1096,20 @@ void RAMFUNC SnoopIso14443(void)
|
||||||
// Setup for the DMA.
|
// Setup for the DMA.
|
||||||
FpgaSetupSsc();
|
FpgaSetupSsc();
|
||||||
upTo = dmaBuf;
|
upTo = dmaBuf;
|
||||||
lastRxCounter = DEMOD_DMA_BUFFER_SIZE;
|
lastRxCounter = DMA_BUFFER_SIZE;
|
||||||
FpgaSetupSscDma((uint8_t *)dmaBuf, DEMOD_DMA_BUFFER_SIZE);
|
FpgaSetupSscDma((uint8_t *)dmaBuf, DMA_BUFFER_SIZE);
|
||||||
|
uint8_t parity[MAX_PARITY_SIZE];
|
||||||
LED_A_ON();
|
LED_A_ON();
|
||||||
|
|
||||||
// And now we loop, receiving samples.
|
// And now we loop, receiving samples.
|
||||||
for(;;) {
|
for(;;) {
|
||||||
int behindBy = (lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR) &
|
int behindBy = (lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR) &
|
||||||
(DEMOD_DMA_BUFFER_SIZE-1);
|
(DMA_BUFFER_SIZE-1);
|
||||||
if(behindBy > maxBehindBy) {
|
if(behindBy > maxBehindBy) {
|
||||||
maxBehindBy = behindBy;
|
maxBehindBy = behindBy;
|
||||||
if(behindBy > (9*DEMOD_DMA_BUFFER_SIZE/10)) { // TODO: understand whether we can increase/decrease as we want or not?
|
if(behindBy > (9*DMA_BUFFER_SIZE/10)) { // TODO: understand whether we can increase/decrease as we want or not?
|
||||||
Dbprintf("blew circular buffer! behindBy=0x%x", behindBy);
|
Dbprintf("blew circular buffer! behindBy=0x%x", behindBy);
|
||||||
goto done;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(behindBy < 2) continue;
|
if(behindBy < 2) continue;
|
||||||
|
@ -1089,89 +1118,71 @@ void RAMFUNC SnoopIso14443(void)
|
||||||
cq = upTo[1];
|
cq = upTo[1];
|
||||||
upTo += 2;
|
upTo += 2;
|
||||||
lastRxCounter -= 2;
|
lastRxCounter -= 2;
|
||||||
if(upTo - dmaBuf > DEMOD_DMA_BUFFER_SIZE) {
|
if(upTo - dmaBuf > DMA_BUFFER_SIZE) {
|
||||||
upTo -= DEMOD_DMA_BUFFER_SIZE;
|
upTo -= DMA_BUFFER_SIZE;
|
||||||
lastRxCounter += DEMOD_DMA_BUFFER_SIZE;
|
lastRxCounter += DMA_BUFFER_SIZE;
|
||||||
AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) upTo;
|
AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) upTo;
|
||||||
AT91C_BASE_PDC_SSC->PDC_RNCR = DEMOD_DMA_BUFFER_SIZE;
|
AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
samples += 2;
|
samples += 2;
|
||||||
|
|
||||||
#define HANDLE_BIT_IF_BODY \
|
|
||||||
if(triggered) { \
|
|
||||||
trace[traceLen++] = ((samples >> 0) & 0xff); \
|
|
||||||
trace[traceLen++] = ((samples >> 8) & 0xff); \
|
|
||||||
trace[traceLen++] = ((samples >> 16) & 0xff); \
|
|
||||||
trace[traceLen++] = ((samples >> 24) & 0xff); \
|
|
||||||
trace[traceLen++] = 0; \
|
|
||||||
trace[traceLen++] = 0; \
|
|
||||||
trace[traceLen++] = 0; \
|
|
||||||
trace[traceLen++] = 0; \
|
|
||||||
trace[traceLen++] = Uart.byteCnt; \
|
|
||||||
memcpy(trace+traceLen, receivedCmd, Uart.byteCnt); \
|
|
||||||
traceLen += Uart.byteCnt; \
|
|
||||||
if(traceLen > 1000) break; \
|
|
||||||
} \
|
|
||||||
/* And ready to receive another command. */ \
|
|
||||||
memset(&Uart, 0, sizeof(Uart)); \
|
|
||||||
Uart.output = receivedCmd; \
|
|
||||||
Uart.byteCntMax = 100; \
|
|
||||||
Uart.state = STATE_UNSYNCD; \
|
|
||||||
/* And also reset the demod code, which might have been */ \
|
|
||||||
/* false-triggered by the commands from the reader. */ \
|
|
||||||
memset(&Demod, 0, sizeof(Demod)); \
|
|
||||||
Demod.output = receivedResponse; \
|
|
||||||
Demod.state = DEMOD_UNSYNCD; \
|
|
||||||
|
|
||||||
if(Handle14443UartBit(ci & 1)) {
|
if(Handle14443UartBit(ci & 1)) {
|
||||||
HANDLE_BIT_IF_BODY
|
if(triggered && tracing) {
|
||||||
|
GetParity(Uart.output, Uart.byteCnt, parity);
|
||||||
|
LogTrace(Uart.output,Uart.byteCnt,samples, samples,parity,TRUE);
|
||||||
|
}
|
||||||
|
if(Uart.byteCnt==0) Dbprintf("[1] Error, Uart.byteCnt==0, Uart.bitCnt=%d", Uart.bitCnt);
|
||||||
|
|
||||||
|
/* And ready to receive another command. */
|
||||||
|
UartReset();
|
||||||
|
/* And also reset the demod code, which might have been */
|
||||||
|
/* false-triggered by the commands from the reader. */
|
||||||
|
DemodReset();
|
||||||
}
|
}
|
||||||
if(Handle14443UartBit(cq & 1)) {
|
if(Handle14443UartBit(cq & 1)) {
|
||||||
HANDLE_BIT_IF_BODY
|
if(triggered && tracing) {
|
||||||
|
GetParity(Uart.output, Uart.byteCnt, parity);
|
||||||
|
LogTrace(Uart.output,Uart.byteCnt,samples, samples,parity,TRUE);
|
||||||
|
}
|
||||||
|
if(Uart.byteCnt==0) Dbprintf("[2] Error, Uart.byteCnt==0, Uart.bitCnt=%d", Uart.bitCnt);
|
||||||
|
|
||||||
|
/* And ready to receive another command. */
|
||||||
|
UartReset();
|
||||||
|
/* And also reset the demod code, which might have been */
|
||||||
|
/* false-triggered by the commands from the reader. */
|
||||||
|
DemodReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Handle14443SamplesDemod(ci, cq)) {
|
if(Handle14443SamplesDemod(ci, cq)) {
|
||||||
// timestamp, as a count of samples
|
|
||||||
trace[traceLen++] = ((samples >> 0) & 0xff);
|
|
||||||
trace[traceLen++] = ((samples >> 8) & 0xff);
|
|
||||||
trace[traceLen++] = ((samples >> 16) & 0xff);
|
|
||||||
trace[traceLen++] = 0x80 | ((samples >> 24) & 0xff);
|
|
||||||
// correlation metric (~signal strength estimate)
|
|
||||||
if(Demod.metricN != 0) {
|
|
||||||
Demod.metric /= Demod.metricN;
|
|
||||||
}
|
|
||||||
trace[traceLen++] = ((Demod.metric >> 0) & 0xff);
|
|
||||||
trace[traceLen++] = ((Demod.metric >> 8) & 0xff);
|
|
||||||
trace[traceLen++] = ((Demod.metric >> 16) & 0xff);
|
|
||||||
trace[traceLen++] = ((Demod.metric >> 24) & 0xff);
|
|
||||||
// length
|
|
||||||
trace[traceLen++] = Demod.len;
|
|
||||||
memcpy(trace+traceLen, receivedResponse, Demod.len);
|
|
||||||
traceLen += Demod.len;
|
|
||||||
if(traceLen > BigBuf_max_traceLen()) {
|
|
||||||
DbpString("Reached trace limit");
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
//Use samples as a time measurement
|
||||||
|
if(tracing)
|
||||||
|
{
|
||||||
|
uint8_t parity[MAX_PARITY_SIZE];
|
||||||
|
GetParity(Demod.output, Demod.len, parity);
|
||||||
|
LogTrace(Demod.output,Demod.len,samples, samples,parity,FALSE);
|
||||||
|
}
|
||||||
triggered = TRUE;
|
triggered = TRUE;
|
||||||
LED_A_OFF();
|
LED_A_OFF();
|
||||||
LED_B_ON();
|
LED_B_ON();
|
||||||
|
|
||||||
// And ready to receive another response.
|
// And ready to receive another response.
|
||||||
memset(&Demod, 0, sizeof(Demod));
|
DemodReset();
|
||||||
Demod.output = receivedResponse;
|
|
||||||
Demod.state = DEMOD_UNSYNCD;
|
|
||||||
}
|
}
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
|
|
||||||
if(BUTTON_PRESS()) {
|
if(!tracing) {
|
||||||
DbpString("cancelled");
|
DbpString("Reached trace limit");
|
||||||
goto done;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
if(BUTTON_PRESS()) {
|
||||||
|
DbpString("cancelled");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FpgaDisableSscDma();
|
||||||
LED_A_OFF();
|
LED_A_OFF();
|
||||||
LED_B_OFF();
|
LED_B_OFF();
|
||||||
LED_C_OFF();
|
LED_C_OFF();
|
||||||
|
@ -1181,7 +1192,7 @@ done:
|
||||||
Dbprintf(" Uart State: %x", Uart.state);
|
Dbprintf(" Uart State: %x", Uart.state);
|
||||||
Dbprintf(" Uart ByteCnt: %i", Uart.byteCnt);
|
Dbprintf(" Uart ByteCnt: %i", Uart.byteCnt);
|
||||||
Dbprintf(" Uart ByteCntMax: %i", Uart.byteCntMax);
|
Dbprintf(" Uart ByteCntMax: %i", Uart.byteCntMax);
|
||||||
Dbprintf(" Trace length: %i", traceLen);
|
Dbprintf(" Trace length: %i", BigBuf_get_traceLen());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1222,8 +1233,8 @@ void SendRawCommand14443B(uint32_t datalen, uint32_t recv,uint8_t powerfield, ui
|
||||||
SpinDelay(200);
|
SpinDelay(200);
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeIso14443bAsReader(data, datalen);
|
CodeAndTransmit14443bAsReader(data, datalen);
|
||||||
TransmitFor14443();
|
|
||||||
if(recv)
|
if(recv)
|
||||||
{
|
{
|
||||||
uint16_t iLen = MIN(Demod.len,USB_CMD_DATA_SIZE);
|
uint16_t iLen = MIN(Demod.len,USB_CMD_DATA_SIZE);
|
||||||
|
|
|
@ -20,10 +20,9 @@
|
||||||
#include "iso14443a.h"
|
#include "iso14443a.h"
|
||||||
#include "crapto1.h"
|
#include "crapto1.h"
|
||||||
#include "mifareutil.h"
|
#include "mifareutil.h"
|
||||||
|
#include "BigBuf.h"
|
||||||
static uint32_t iso14a_timeout;
|
static uint32_t iso14a_timeout;
|
||||||
int rsamples = 0;
|
int rsamples = 0;
|
||||||
int tracing = TRUE;
|
|
||||||
uint8_t trigger = 0;
|
uint8_t trigger = 0;
|
||||||
// the block number for the ISO14443-4 PCB
|
// the block number for the ISO14443-4 PCB
|
||||||
static uint8_t iso14_pcb_blocknum = 0;
|
static uint8_t iso14_pcb_blocknum = 0;
|
||||||
|
@ -146,16 +145,7 @@ void iso14a_set_trigger(bool enable) {
|
||||||
trigger = enable;
|
trigger = enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
void iso14a_clear_trace() {
|
|
||||||
uint8_t *trace = BigBuf_get_addr();
|
|
||||||
uint16_t max_traceLen = BigBuf_max_traceLen();
|
|
||||||
memset(trace, 0x44, max_traceLen);
|
|
||||||
traceLen = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void iso14a_set_tracing(bool enable) {
|
|
||||||
tracing = enable;
|
|
||||||
}
|
|
||||||
|
|
||||||
void iso14a_set_timeout(uint32_t timeout) {
|
void iso14a_set_timeout(uint32_t timeout) {
|
||||||
iso14a_timeout = timeout;
|
iso14a_timeout = timeout;
|
||||||
|
@ -199,63 +189,6 @@ void AppendCrc14443a(uint8_t* data, int len)
|
||||||
ComputeCrc14443(CRC_14443_A,data,len,data+len,data+len+1);
|
ComputeCrc14443(CRC_14443_A,data,len,data+len,data+len+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The function LogTrace() is also used by the iClass implementation in iClass.c
|
|
||||||
bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag)
|
|
||||||
{
|
|
||||||
if (!tracing) return FALSE;
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
// Return when trace is full
|
|
||||||
uint16_t max_traceLen = BigBuf_max_traceLen();
|
|
||||||
if (traceLen + sizeof(iLen) + sizeof(timestamp_start) + sizeof(duration) + num_paritybytes + iLen >= max_traceLen) {
|
|
||||||
tracing = FALSE; // don't trace any more
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Traceformat:
|
|
||||||
// 32 bits timestamp (little endian)
|
|
||||||
// 16 bits duration (little endian)
|
|
||||||
// 16 bits data length (little endian, Highest Bit used as readerToTag flag)
|
|
||||||
// y Bytes data
|
|
||||||
// x Bytes parity (one byte per 8 bytes data)
|
|
||||||
|
|
||||||
// timestamp (start)
|
|
||||||
trace[traceLen++] = ((timestamp_start >> 0) & 0xff);
|
|
||||||
trace[traceLen++] = ((timestamp_start >> 8) & 0xff);
|
|
||||||
trace[traceLen++] = ((timestamp_start >> 16) & 0xff);
|
|
||||||
trace[traceLen++] = ((timestamp_start >> 24) & 0xff);
|
|
||||||
|
|
||||||
// duration
|
|
||||||
trace[traceLen++] = ((duration >> 0) & 0xff);
|
|
||||||
trace[traceLen++] = ((duration >> 8) & 0xff);
|
|
||||||
|
|
||||||
// data length
|
|
||||||
trace[traceLen++] = ((iLen >> 0) & 0xff);
|
|
||||||
trace[traceLen++] = ((iLen >> 8) & 0xff);
|
|
||||||
|
|
||||||
// readerToTag flag
|
|
||||||
if (!readerToTag) {
|
|
||||||
trace[traceLen - 1] |= 0x80;
|
|
||||||
}
|
|
||||||
|
|
||||||
// data bytes
|
|
||||||
if (btBytes != NULL && iLen != 0) {
|
|
||||||
memcpy(trace + traceLen, btBytes, iLen);
|
|
||||||
}
|
|
||||||
traceLen += iLen;
|
|
||||||
|
|
||||||
// parity bytes
|
|
||||||
if (parity != NULL && iLen != 0) {
|
|
||||||
memcpy(trace + traceLen, parity, num_paritybytes);
|
|
||||||
}
|
|
||||||
traceLen += num_paritybytes;
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
// ISO 14443 Type A - Miller decoder
|
// ISO 14443 Type A - Miller decoder
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
@ -616,8 +549,8 @@ void RAMFUNC SnoopIso14443a(uint8_t param) {
|
||||||
uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE);
|
uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE);
|
||||||
|
|
||||||
// init trace buffer
|
// init trace buffer
|
||||||
iso14a_clear_trace();
|
clear_trace();
|
||||||
iso14a_set_tracing(TRUE);
|
set_tracing(TRUE);
|
||||||
|
|
||||||
uint8_t *data = dmaBuf;
|
uint8_t *data = dmaBuf;
|
||||||
uint8_t previous_data = 0;
|
uint8_t previous_data = 0;
|
||||||
|
@ -741,7 +674,7 @@ void RAMFUNC SnoopIso14443a(uint8_t param) {
|
||||||
|
|
||||||
FpgaDisableSscDma();
|
FpgaDisableSscDma();
|
||||||
Dbprintf("maxDataLen=%d, Uart.state=%x, Uart.len=%d", maxDataLen, Uart.state, Uart.len);
|
Dbprintf("maxDataLen=%d, Uart.state=%x, Uart.len=%d", maxDataLen, Uart.state, Uart.len);
|
||||||
Dbprintf("traceLen=%d, Uart.output[0]=%08x", traceLen, (uint32_t)Uart.output[0]);
|
Dbprintf("traceLen=%d, Uart.output[0]=%08x", BigBuf_get_traceLen(), (uint32_t)Uart.output[0]);
|
||||||
LEDsoff();
|
LEDsoff();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1077,8 +1010,8 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data)
|
||||||
free_buffer_pointer = BigBuf_malloc(ALLOCATED_TAG_MODULATION_BUFFER_SIZE);
|
free_buffer_pointer = BigBuf_malloc(ALLOCATED_TAG_MODULATION_BUFFER_SIZE);
|
||||||
|
|
||||||
// clear trace
|
// clear trace
|
||||||
iso14a_clear_trace();
|
clear_trace();
|
||||||
iso14a_set_tracing(TRUE);
|
set_tracing(TRUE);
|
||||||
|
|
||||||
// Prepare the responses of the anticollision phase
|
// Prepare the responses of the anticollision phase
|
||||||
// there will be not enough time to do this at the moment the reader sends it REQA
|
// there will be not enough time to do this at the moment the reader sends it REQA
|
||||||
|
@ -1936,10 +1869,10 @@ void ReaderIso14443a(UsbCommand *c)
|
||||||
uint8_t par[MAX_PARITY_SIZE];
|
uint8_t par[MAX_PARITY_SIZE];
|
||||||
|
|
||||||
if(param & ISO14A_CONNECT) {
|
if(param & ISO14A_CONNECT) {
|
||||||
iso14a_clear_trace();
|
clear_trace();
|
||||||
}
|
}
|
||||||
|
|
||||||
iso14a_set_tracing(TRUE);
|
set_tracing(TRUE);
|
||||||
|
|
||||||
if(param & ISO14A_REQUEST_TRIGGER) {
|
if(param & ISO14A_REQUEST_TRIGGER) {
|
||||||
iso14a_set_trigger(TRUE);
|
iso14a_set_trigger(TRUE);
|
||||||
|
@ -2035,8 +1968,8 @@ void ReaderMifare(bool first_try)
|
||||||
// free eventually allocated BigBuf memory. We want all for tracing.
|
// free eventually allocated BigBuf memory. We want all for tracing.
|
||||||
BigBuf_free();
|
BigBuf_free();
|
||||||
|
|
||||||
iso14a_clear_trace();
|
clear_trace();
|
||||||
iso14a_set_tracing(TRUE);
|
set_tracing(TRUE);
|
||||||
|
|
||||||
byte_t nt_diff = 0;
|
byte_t nt_diff = 0;
|
||||||
uint8_t par[1] = {0}; // maximum 8 Bytes to be sent here, 1 byte parity is therefore enough
|
uint8_t par[1] = {0}; // maximum 8 Bytes to be sent here, 1 byte parity is therefore enough
|
||||||
|
@ -2209,7 +2142,7 @@ void ReaderMifare(bool first_try)
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
LEDsoff();
|
LEDsoff();
|
||||||
|
|
||||||
iso14a_set_tracing(FALSE);
|
set_tracing(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2268,8 +2201,8 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
|
||||||
BigBuf_free_keep_EM();
|
BigBuf_free_keep_EM();
|
||||||
|
|
||||||
// clear trace
|
// clear trace
|
||||||
iso14a_clear_trace();
|
clear_trace();
|
||||||
iso14a_set_tracing(TRUE);
|
set_tracing(TRUE);
|
||||||
|
|
||||||
// Authenticate response - nonce
|
// Authenticate response - nonce
|
||||||
uint32_t nonce = bytes_to_num(rAUTH_NT, 4);
|
uint32_t nonce = bytes_to_num(rAUTH_NT, 4);
|
||||||
|
@ -2714,7 +2647,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (MF_DBGLEVEL >= 1) Dbprintf("Emulator stopped. Tracing: %d trace length: %d ", tracing, traceLen);
|
if (MF_DBGLEVEL >= 1) Dbprintf("Emulator stopped. Tracing: %d trace length: %d ", tracing, BigBuf_get_traceLen());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2732,8 +2665,8 @@ void RAMFUNC SniffMifare(uint8_t param) {
|
||||||
// C(red) A(yellow) B(green)
|
// C(red) A(yellow) B(green)
|
||||||
LEDsoff();
|
LEDsoff();
|
||||||
// init trace buffer
|
// init trace buffer
|
||||||
iso14a_clear_trace();
|
clear_trace();
|
||||||
iso14a_set_tracing(TRUE);
|
set_tracing(TRUE);
|
||||||
|
|
||||||
// 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.
|
// The length of a received command will in most cases be no more than 18 bytes.
|
||||||
|
|
|
@ -87,7 +87,4 @@ extern int iso14443a_select_card(uint8_t *uid_ptr, iso14a_card_select_t *resp_da
|
||||||
extern void iso14a_set_trigger(bool enable);
|
extern void iso14a_set_trigger(bool enable);
|
||||||
extern void iso14a_set_timeout(uint32_t timeout);
|
extern void iso14a_set_timeout(uint32_t timeout);
|
||||||
|
|
||||||
extern void iso14a_clear_trace();
|
|
||||||
extern void iso14a_set_tracing(bool enable);
|
|
||||||
|
|
||||||
#endif /* __ISO14443A_H */
|
#endif /* __ISO14443A_H */
|
||||||
|
|
|
@ -41,7 +41,7 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
|
||||||
pcs = &mpcs;
|
pcs = &mpcs;
|
||||||
|
|
||||||
// clear trace
|
// clear trace
|
||||||
iso14a_clear_trace();
|
clear_trace();
|
||||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||||
|
|
||||||
LED_A_ON();
|
LED_A_ON();
|
||||||
|
@ -98,7 +98,7 @@ void MifareUC_Auth1(uint8_t arg0, uint8_t *datain){
|
||||||
LED_B_OFF();
|
LED_B_OFF();
|
||||||
LED_C_OFF();
|
LED_C_OFF();
|
||||||
|
|
||||||
iso14a_clear_trace();
|
clear_trace();
|
||||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||||
|
|
||||||
if(!iso14443a_select_card(uid, NULL, &cuid)) {
|
if(!iso14443a_select_card(uid, NULL, &cuid)) {
|
||||||
|
@ -162,7 +162,7 @@ void MifareUReadBlock(uint8_t arg0,uint8_t *datain)
|
||||||
LED_B_OFF();
|
LED_B_OFF();
|
||||||
LED_C_OFF();
|
LED_C_OFF();
|
||||||
|
|
||||||
iso14a_clear_trace();
|
clear_trace();
|
||||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||||
|
|
||||||
int len = iso14443a_select_card(uid, NULL, &cuid);
|
int len = iso14443a_select_card(uid, NULL, &cuid);
|
||||||
|
@ -213,7 +213,7 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
|
||||||
pcs = &mpcs;
|
pcs = &mpcs;
|
||||||
|
|
||||||
// clear trace
|
// clear trace
|
||||||
iso14a_clear_trace();
|
clear_trace();
|
||||||
|
|
||||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||||
|
|
||||||
|
@ -276,7 +276,7 @@ void MifareUReadCard(uint8_t arg0, int arg1, uint8_t *datain)
|
||||||
if (MF_DBGLEVEL >= MF_DBG_ALL)
|
if (MF_DBGLEVEL >= MF_DBG_ALL)
|
||||||
Dbprintf("Pages %d",Pages);
|
Dbprintf("Pages %d",Pages);
|
||||||
|
|
||||||
iso14a_clear_trace();
|
clear_trace();
|
||||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||||
|
|
||||||
int len = iso14443a_select_card(uid, NULL, &cuid);
|
int len = iso14443a_select_card(uid, NULL, &cuid);
|
||||||
|
@ -350,7 +350,7 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
|
||||||
pcs = &mpcs;
|
pcs = &mpcs;
|
||||||
|
|
||||||
// clear trace
|
// clear trace
|
||||||
iso14a_clear_trace();
|
clear_trace();
|
||||||
|
|
||||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||||
|
|
||||||
|
@ -411,7 +411,7 @@ void MifareUWriteBlock(uint8_t arg0, uint8_t *datain)
|
||||||
uint8_t uid[10] = {0x00};
|
uint8_t uid[10] = {0x00};
|
||||||
uint32_t cuid;
|
uint32_t cuid;
|
||||||
|
|
||||||
iso14a_clear_trace();
|
clear_trace();
|
||||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||||
|
|
||||||
LED_A_ON();
|
LED_A_ON();
|
||||||
|
@ -458,7 +458,7 @@ void MifareUWriteBlock_Special(uint8_t arg0, uint8_t *datain)
|
||||||
uint8_t uid[10] = {0x00};
|
uint8_t uid[10] = {0x00};
|
||||||
uint32_t cuid;
|
uint32_t cuid;
|
||||||
|
|
||||||
iso14a_clear_trace();
|
clear_trace();
|
||||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||||
|
|
||||||
LED_A_ON();
|
LED_A_ON();
|
||||||
|
@ -537,8 +537,8 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
|
||||||
// free eventually allocated BigBuf memory
|
// free eventually allocated BigBuf memory
|
||||||
BigBuf_free();
|
BigBuf_free();
|
||||||
// clear trace
|
// clear trace
|
||||||
iso14a_clear_trace();
|
clear_trace();
|
||||||
iso14a_set_tracing(false);
|
set_tracing(false);
|
||||||
|
|
||||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||||
|
|
||||||
|
@ -709,7 +709,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
|
||||||
|
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
LEDsoff();
|
LEDsoff();
|
||||||
iso14a_set_tracing(TRUE);
|
set_tracing(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -738,8 +738,8 @@ void MifareChkKeys(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
|
||||||
MF_DBGLEVEL = MF_DBG_NONE;
|
MF_DBGLEVEL = MF_DBG_NONE;
|
||||||
|
|
||||||
// clear trace
|
// clear trace
|
||||||
iso14a_clear_trace();
|
clear_trace();
|
||||||
iso14a_set_tracing(TRUE);
|
set_tracing(TRUE);
|
||||||
|
|
||||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||||
|
|
||||||
|
@ -829,8 +829,8 @@ void MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
|
||||||
uint8_t uid[10];
|
uint8_t uid[10];
|
||||||
|
|
||||||
// clear trace
|
// clear trace
|
||||||
iso14a_clear_trace();
|
clear_trace();
|
||||||
iso14a_set_tracing(false);
|
set_tracing(false);
|
||||||
|
|
||||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||||
|
|
||||||
|
@ -931,8 +931,8 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
|
||||||
LED_B_OFF();
|
LED_B_OFF();
|
||||||
LED_C_OFF();
|
LED_C_OFF();
|
||||||
|
|
||||||
iso14a_clear_trace();
|
clear_trace();
|
||||||
iso14a_set_tracing(TRUE);
|
set_tracing(TRUE);
|
||||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1049,8 +1049,8 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
|
||||||
LED_B_OFF();
|
LED_B_OFF();
|
||||||
LED_C_OFF();
|
LED_C_OFF();
|
||||||
|
|
||||||
iso14a_clear_trace();
|
clear_trace();
|
||||||
iso14a_set_tracing(TRUE);
|
set_tracing(TRUE);
|
||||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1136,7 +1136,7 @@ void Mifare_DES_Auth1(uint8_t arg0, uint8_t *datain){
|
||||||
uint8_t uid[10] = {0x00};
|
uint8_t uid[10] = {0x00};
|
||||||
uint32_t cuid;
|
uint32_t cuid;
|
||||||
|
|
||||||
iso14a_clear_trace();
|
clear_trace();
|
||||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||||
|
|
||||||
int len = iso14443a_select_card(uid, NULL, &cuid);
|
int len = iso14443a_select_card(uid, NULL, &cuid);
|
||||||
|
|
|
@ -139,7 +139,7 @@ bool RAMFUNC MfSniffLogic(const uint8_t *data, uint16_t len, uint8_t *parity, ui
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RAMFUNC MfSniffSend(uint16_t maxTimeoutMs) {
|
bool RAMFUNC MfSniffSend(uint16_t maxTimeoutMs) {
|
||||||
if (traceLen && (GetTickCount() > timerData + maxTimeoutMs)) {
|
if (BigBuf_get_traceLen() && (GetTickCount() > timerData + maxTimeoutMs)) {
|
||||||
return intMfSniffSend();
|
return intMfSniffSend();
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -149,7 +149,7 @@ bool RAMFUNC MfSniffSend(uint16_t maxTimeoutMs) {
|
||||||
bool intMfSniffSend() {
|
bool intMfSniffSend() {
|
||||||
|
|
||||||
int pckSize = 0;
|
int pckSize = 0;
|
||||||
int pckLen = traceLen;
|
int pckLen = BigBuf_get_traceLen();
|
||||||
int pckNum = 0;
|
int pckNum = 0;
|
||||||
uint8_t *trace = BigBuf_get_addr();
|
uint8_t *trace = BigBuf_get_addr();
|
||||||
|
|
||||||
|
@ -157,7 +157,7 @@ bool intMfSniffSend() {
|
||||||
while (pckLen > 0) {
|
while (pckLen > 0) {
|
||||||
pckSize = MIN(USB_CMD_DATA_SIZE, pckLen);
|
pckSize = MIN(USB_CMD_DATA_SIZE, pckLen);
|
||||||
LED_B_ON();
|
LED_B_ON();
|
||||||
cmd_send(CMD_ACK, 1, traceLen, pckSize, trace + traceLen - pckLen, pckSize);
|
cmd_send(CMD_ACK, 1, BigBuf_get_traceLen(), pckSize, trace + BigBuf_get_traceLen() - pckLen, pckSize);
|
||||||
LED_B_OFF();
|
LED_B_OFF();
|
||||||
|
|
||||||
pckLen -= pckSize;
|
pckLen -= pckSize;
|
||||||
|
@ -168,7 +168,7 @@ bool intMfSniffSend() {
|
||||||
cmd_send(CMD_ACK,2,0,0,0,0);
|
cmd_send(CMD_ACK,2,0,0,0,0);
|
||||||
LED_B_OFF();
|
LED_B_OFF();
|
||||||
|
|
||||||
iso14a_clear_trace();
|
clear_trace();
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include "apps.h"
|
#include "apps.h"
|
||||||
|
#include "BigBuf.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -34,7 +35,7 @@ void print_result(char *name, uint8_t *buf, size_t len) {
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t nbytes(size_t nbits) {
|
size_t nbytes(size_t nbits) {
|
||||||
return (nbits/8)+((nbits%8)>0);
|
return (nbits >> 3)+((nbits % 8) > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t SwapBits(uint32_t value, int nrbits) {
|
uint32_t SwapBits(uint32_t value, int nrbits) {
|
||||||
|
@ -428,4 +429,3 @@ uint32_t RAMFUNC GetCountSspClk(){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -157,9 +157,28 @@ NXP/Philips CUSTOM COMMANDS
|
||||||
#define MIFARE_ULC_AUTH_1 0x1A
|
#define MIFARE_ULC_AUTH_1 0x1A
|
||||||
#define MIFARE_ULC_AUTH_2 0xAF
|
#define MIFARE_ULC_AUTH_2 0xAF
|
||||||
|
|
||||||
|
/**
|
||||||
|
06 00 = INITIATE
|
||||||
|
0E xx = SELECT ID (xx = Chip-ID)
|
||||||
|
0B = Get UID
|
||||||
|
08 yy = Read Block (yy = block number)
|
||||||
|
09 yy dd dd dd dd = Write Block (yy = block number; dd dd dd dd = data to be written)
|
||||||
|
0C = Reset to Inventory
|
||||||
|
0F = Completion
|
||||||
|
0A 11 22 33 44 55 66 = Authenticate (11 22 33 44 55 66 = data to authenticate)
|
||||||
|
**/
|
||||||
|
|
||||||
#define ISO14443B_REQB 0x05
|
#define ISO14443B_REQB 0x05
|
||||||
#define ISO14443B_ATTRIB 0x1D
|
#define ISO14443B_ATTRIB 0x1D
|
||||||
#define ISO14443B_HALT 0x50
|
#define ISO14443B_HALT 0x50
|
||||||
|
#define ISO14443B_INITIATE 0x06
|
||||||
|
#define ISO14443B_SELECT 0x0E
|
||||||
|
#define ISO14443B_GET_UID 0x0B
|
||||||
|
#define ISO14443B_READ_BLK 0x08
|
||||||
|
#define ISO14443B_WRITE_BLK 0x09
|
||||||
|
#define ISO14443B_RESET 0x0C
|
||||||
|
#define ISO14443B_COMPLETION 0x0F
|
||||||
|
#define ISO14443B_AUTHENTICATE 0x0A
|
||||||
|
|
||||||
//First byte is 26
|
//First byte is 26
|
||||||
#define ISO15693_INVENTORY 0x01
|
#define ISO15693_INVENTORY 0x01
|
||||||
|
@ -287,13 +306,33 @@ void annotateIso15693(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
06 00 = INITIATE
|
||||||
|
0E xx = SELECT ID (xx = Chip-ID)
|
||||||
|
0B = Get UID
|
||||||
|
08 yy = Read Block (yy = block number)
|
||||||
|
09 yy dd dd dd dd = Write Block (yy = block number; dd dd dd dd = data to be written)
|
||||||
|
0C = Reset to Inventory
|
||||||
|
0F = Completion
|
||||||
|
0A 11 22 33 44 55 66 = Authenticate (11 22 33 44 55 66 = data to authenticate)
|
||||||
|
**/
|
||||||
|
|
||||||
void annotateIso14443b(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize)
|
void annotateIso14443b(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize)
|
||||||
{
|
{
|
||||||
switch(cmd[0]){
|
switch(cmd[0]){
|
||||||
case ISO14443B_REQB : snprintf(exp,size,"REQB");break;
|
case ISO14443B_REQB : snprintf(exp,size,"REQB");break;
|
||||||
case ISO14443B_ATTRIB : snprintf(exp,size,"ATTRIB");break;
|
case ISO14443B_ATTRIB : snprintf(exp,size,"ATTRIB");break;
|
||||||
case ISO14443B_HALT : snprintf(exp,size,"HALT");break;
|
case ISO14443B_HALT : snprintf(exp,size,"HALT");break;
|
||||||
default: snprintf(exp,size ,"?");break;
|
case ISO14443B_INITIATE : snprintf(exp,size,"INITIATE");break;
|
||||||
|
case ISO14443B_SELECT : snprintf(exp,size,"SELECT(%d)",cmd[1]);break;
|
||||||
|
case ISO14443B_GET_UID : snprintf(exp,size,"GET UID");break;
|
||||||
|
case ISO14443B_READ_BLK : snprintf(exp,size,"READ_BLK(%d)", cmd[1]);break;
|
||||||
|
case ISO14443B_WRITE_BLK : snprintf(exp,size,"WRITE_BLK(%d)",cmd[1]);break;
|
||||||
|
case ISO14443B_RESET : snprintf(exp,size,"RESET");break;
|
||||||
|
case ISO14443B_COMPLETION : snprintf(exp,size,"COMPLETION");break;
|
||||||
|
case ISO14443B_AUTHENTICATE : snprintf(exp,size,"AUTHENTICATE");break;
|
||||||
|
default : snprintf(exp,size ,"?");break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -412,15 +451,18 @@ uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, ui
|
||||||
if (tracepos + data_len + parity_len > traceLen) {
|
if (tracepos + data_len + parity_len > traceLen) {
|
||||||
return traceLen;
|
return traceLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *frame = trace + tracepos;
|
uint8_t *frame = trace + tracepos;
|
||||||
tracepos += data_len;
|
tracepos += data_len;
|
||||||
uint8_t *parityBytes = trace + tracepos;
|
uint8_t *parityBytes = trace + tracepos;
|
||||||
tracepos += parity_len;
|
tracepos += parity_len;
|
||||||
|
|
||||||
|
|
||||||
//--- Draw the data column
|
//--- Draw the data column
|
||||||
|
//char line[16][110];
|
||||||
char line[16][110];
|
char line[16][110];
|
||||||
for (int j = 0; j < data_len; j++) {
|
|
||||||
|
for (int j = 0; j < data_len && j/16 < 16; j++) {
|
||||||
|
|
||||||
int oddparity = 0x01;
|
int oddparity = 0x01;
|
||||||
int k;
|
int k;
|
||||||
|
|
||||||
|
@ -429,11 +471,17 @@ uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, ui
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t parityBits = parityBytes[j>>3];
|
uint8_t parityBits = parityBytes[j>>3];
|
||||||
|
|
||||||
if (isResponse && (oddparity != ((parityBits >> (7-(j&0x0007))) & 0x01))) {
|
if (isResponse && (oddparity != ((parityBits >> (7-(j&0x0007))) & 0x01))) {
|
||||||
sprintf(line[j/16]+((j%16)*4), "%02x! ", frame[j]);
|
snprintf(line[j/16]+(( j % 16) * 4),110, "%02x! ", frame[j]);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
sprintf(line[j/16]+((j%16)*4), "%02x ", frame[j]);
|
snprintf(line[j/16]+(( j % 16) * 4),110, "%02x! ", frame[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(data_len == 0)
|
||||||
|
{
|
||||||
|
if(data_len == 0){
|
||||||
|
sprintf(line[0],"<empty trace - possible error>");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//--- Draw the CRC column
|
//--- Draw the CRC column
|
||||||
|
@ -478,8 +526,8 @@ uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, ui
|
||||||
annotateIso14443b(explanation,sizeof(explanation),frame,data_len);
|
annotateIso14443b(explanation,sizeof(explanation),frame,data_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
int num_lines = (data_len - 1)/16 + 1;
|
int num_lines = MIN((data_len - 1)/16 + 1, 16);
|
||||||
for (int j = 0; j < num_lines; j++) {
|
for (int j = 0; j < num_lines ; j++) {
|
||||||
if (j == 0) {
|
if (j == 0) {
|
||||||
PrintAndLog(" %9d | %9d | %s | %-64s| %s| %s",
|
PrintAndLog(" %9d | %9d | %s | %-64s| %s| %s",
|
||||||
(timestamp - first_timestamp),
|
(timestamp - first_timestamp),
|
||||||
|
|
|
@ -145,97 +145,10 @@ demodError:
|
||||||
|
|
||||||
int CmdHF14BList(const char *Cmd)
|
int CmdHF14BList(const char *Cmd)
|
||||||
{
|
{
|
||||||
uint8_t *got = malloc(USB_CMD_DATA_SIZE);
|
PrintAndLog("Deprecated command, use 'hf list 14b' instead");
|
||||||
|
|
||||||
// Query for the actual size of the trace
|
|
||||||
UsbCommand response;
|
|
||||||
GetFromBigBuf(got, USB_CMD_DATA_SIZE, 0);
|
|
||||||
WaitForResponse(CMD_ACK, &response);
|
|
||||||
uint16_t traceLen = response.arg[2];
|
|
||||||
if (traceLen > USB_CMD_DATA_SIZE) {
|
|
||||||
uint8_t *p = realloc(got, traceLen);
|
|
||||||
if (p == NULL) {
|
|
||||||
PrintAndLog("Cannot allocate memory for trace");
|
|
||||||
free(got);
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
got = p;
|
|
||||||
GetFromBigBuf(got, traceLen, 0);
|
|
||||||
WaitForResponse(CMD_ACK,NULL);
|
|
||||||
}
|
|
||||||
PrintAndLog("recorded activity: (TraceLen = %d bytes)", traceLen);
|
|
||||||
PrintAndLog(" time :rssi: who bytes");
|
|
||||||
PrintAndLog("---------+----+----+-----------");
|
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
int prev = -1;
|
|
||||||
|
|
||||||
for(;;) {
|
|
||||||
|
|
||||||
if(i >= traceLen) { break; }
|
|
||||||
|
|
||||||
bool isResponse;
|
|
||||||
int timestamp = *((uint32_t *)(got+i));
|
|
||||||
if(timestamp & 0x80000000) {
|
|
||||||
timestamp &= 0x7fffffff;
|
|
||||||
isResponse = 1;
|
|
||||||
} else {
|
|
||||||
isResponse = 0;
|
|
||||||
}
|
|
||||||
int metric = *((uint32_t *)(got+i+4));
|
|
||||||
|
|
||||||
int len = got[i+8];
|
|
||||||
|
|
||||||
if(len > 100) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(i + len >= traceLen) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t *frame = (got+i+9);
|
|
||||||
|
|
||||||
// Break and stick with current result if buffer was not completely full
|
|
||||||
if (frame[0] == 0x44 && frame[1] == 0x44 && frame[2] == 0x44 && frame[3] == 0x44) break;
|
|
||||||
|
|
||||||
char line[1000] = "";
|
|
||||||
int j;
|
|
||||||
for(j = 0; j < len; j++) {
|
|
||||||
sprintf(line+(j*3), "%02x ", frame[j]);
|
|
||||||
}
|
|
||||||
|
|
||||||
char *crc;
|
|
||||||
if(len > 2) {
|
|
||||||
uint8_t b1, b2;
|
|
||||||
ComputeCrc14443(CRC_14443_B, frame, len-2, &b1, &b2);
|
|
||||||
if(b1 != frame[len-2] || b2 != frame[len-1]) {
|
|
||||||
crc = "**FAIL CRC**";
|
|
||||||
} else {
|
|
||||||
crc = "";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
crc = "(SHORT)";
|
|
||||||
}
|
|
||||||
|
|
||||||
char metricString[100];
|
|
||||||
if(isResponse) {
|
|
||||||
sprintf(metricString, "%3d", metric);
|
|
||||||
} else {
|
|
||||||
strcpy(metricString, " ");
|
|
||||||
}
|
|
||||||
|
|
||||||
PrintAndLog(" +%7d: %s: %s %s %s",
|
|
||||||
(prev < 0 ? 0 : timestamp - prev),
|
|
||||||
metricString,
|
|
||||||
(isResponse ? "TAG" : " "), line, crc);
|
|
||||||
|
|
||||||
prev = timestamp;
|
|
||||||
i += (len + 9);
|
|
||||||
}
|
|
||||||
free(got);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdHF14BRead(const char *Cmd)
|
int CmdHF14BRead(const char *Cmd)
|
||||||
{
|
{
|
||||||
UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443, {strtol(Cmd, NULL, 0), 0, 0}};
|
UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443, {strtol(Cmd, NULL, 0), 0, 0}};
|
||||||
|
@ -473,7 +386,7 @@ static command_t CommandTable[] =
|
||||||
{
|
{
|
||||||
{"help", CmdHelp, 1, "This help"},
|
{"help", CmdHelp, 1, "This help"},
|
||||||
{"demod", CmdHF14BDemod, 1, "Demodulate ISO14443 Type B from tag"},
|
{"demod", CmdHF14BDemod, 1, "Demodulate ISO14443 Type B from tag"},
|
||||||
{"list", CmdHF14BList, 0, "List ISO 14443 history"},
|
{"list", CmdHF14BList, 0, "[Deprecated] List ISO 14443b history"},
|
||||||
{"read", CmdHF14BRead, 0, "Read HF tag (ISO 14443)"},
|
{"read", CmdHF14BRead, 0, "Read HF tag (ISO 14443)"},
|
||||||
{"sim", CmdHF14Sim, 0, "Fake ISO 14443 tag"},
|
{"sim", CmdHF14Sim, 0, "Fake ISO 14443 tag"},
|
||||||
{"simlisten", CmdHFSimlisten, 0, "Get HF samples as fake tag"},
|
{"simlisten", CmdHFSimlisten, 0, "Get HF samples as fake tag"},
|
||||||
|
|
|
@ -7,4 +7,12 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
# proxmark3
|
# proxmark3
|
||||||
|
ACTION!="add|change", GOTO="mm_usb_device_blacklist_end"
|
||||||
|
SUBSYSTEM!="tty", GOTO="mm_ignore"
|
||||||
|
|
||||||
|
ATTRS{idVendor}=="2d2d" ATTRS{idProduct}=="504d", ENV{ID_MM_DEVICE_IGNORE}="1" SYMLINK+="pm3-%n"
|
||||||
|
|
||||||
|
LABEL="mm_ignore"
|
||||||
ATTRS{idVendor}=="2d2d" ATTRS{idProduct}=="504d", ENV{ID_MM_DEVICE_IGNORE}="1"
|
ATTRS{idVendor}=="2d2d" ATTRS{idProduct}=="504d", ENV{ID_MM_DEVICE_IGNORE}="1"
|
||||||
|
|
||||||
|
LABEL="mm_usb_device_blacklist_end"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue