fixing iso 14443b (issue #103):

- fix: treat empty commands as error
- deleting dead code
- rename USB-Commands (ISO14443 -> iso14443B)
This commit is contained in:
pwpiwi 2015-06-18 09:49:22 +02:00
parent d5875804a3
commit 132a02179c
6 changed files with 42 additions and 250 deletions

View file

@ -250,55 +250,6 @@ void MeasureAntennaTuningHf(void)
}
void SimulateTagHfListen(void)
{
// ToDo: historically this used the free buffer, which was 2744 Bytes long.
// There might be a better size to be defined:
#define HF_14B_SNOOP_BUFFER_SIZE 2744
uint8_t *dest = BigBuf_malloc(HF_14B_SNOOP_BUFFER_SIZE);
uint8_t v = 0;
int i;
int p = 0;
// We're using this mode just so that I can test it out; the simulated
// tag mode would work just as well and be simpler.
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_SNOOP);
// We need to listen to the high-frequency, peak-detected path.
SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
FpgaSetupSsc();
i = 0;
for(;;) {
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
AT91C_BASE_SSC->SSC_THR = 0xff;
}
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
uint8_t r = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
v <<= 1;
if(r & 1) {
v |= 1;
}
p++;
if(p >= 8) {
dest[i] = v;
v = 0;
p = 0;
i++;
if(i >= HF_14B_SNOOP_BUFFER_SIZE) {
break;
}
}
}
}
DbpString("simulate tag (now type bitsamples)");
}
void ReadMem(int addr)
{
const uint8_t *data = ((uint8_t *)addr);
@ -782,19 +733,16 @@ void UsbPacketReceived(uint8_t *packet, int len)
#endif
#ifdef WITH_ISO14443b
case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443:
AcquireRawAdcSamplesIso14443b(c->arg[0]);
break;
case CMD_READ_SRI512_TAG:
ReadSTMemoryIso14443b(0x0F);
break;
case CMD_READ_SRIX4K_TAG:
ReadSTMemoryIso14443b(0x7F);
break;
case CMD_SNOOP_ISO_14443:
case CMD_SNOOP_ISO_14443B:
SnoopIso14443b();
break;
case CMD_SIMULATE_TAG_ISO_14443:
case CMD_SIMULATE_TAG_ISO_14443B:
SimulateIso14443bTag();
break;
case CMD_ISO_14443B_COMMAND:
@ -911,10 +859,6 @@ void UsbPacketReceived(uint8_t *packet, int len)
break;
#endif
case CMD_SIMULATE_TAG_HF_LISTEN:
SimulateTagHfListen();
break;
case CMD_BUFF_CLEAR:
BigBuf_Clear();
break;

View file

@ -237,7 +237,11 @@ static int Handle14443bUartBit(int bit)
} else if(Uart.shiftReg == 0x000) {
// this is an EOF byte
LED_A_OFF(); // Finished receiving
return TRUE;
if (Uart.byteCnt != 0) {
return TRUE;
}
Uart.posCnt = 0;
Uart.state = STATE_ERROR_WAIT;
} else {
// this is an error
Uart.posCnt = 0;
@ -714,16 +718,16 @@ static void GetSamplesFor14443bDemod(int n, bool quiet)
uint8_t *receivedResponse = BigBuf_malloc(MAX_FRAME_SIZE);
// 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(DMA_BUFFER_SIZE);
// Set up the demodulator for tag -> reader responses.
DemodInit(receivedResponse);
// Setup and start DMA.
FpgaSetupSscDma((uint8_t*) dmaBuf, ISO14443B_DMA_BUFFER_SIZE);
FpgaSetupSscDma((uint8_t*) dmaBuf, DMA_BUFFER_SIZE);
int8_t *upTo = dmaBuf;
lastRxCounter = ISO14443B_DMA_BUFFER_SIZE;
lastRxCounter = DMA_BUFFER_SIZE;
// Signal field is ON with the appropriate LED:
LED_D_ON();
@ -734,18 +738,18 @@ static void GetSamplesFor14443bDemod(int n, bool quiet)
int behindBy = lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR;
if(behindBy > max) max = behindBy;
while(((lastRxCounter-AT91C_BASE_PDC_SSC->PDC_RCR) & (ISO14443B_DMA_BUFFER_SIZE-1)) > 2) {
while(((lastRxCounter-AT91C_BASE_PDC_SSC->PDC_RCR) & (DMA_BUFFER_SIZE-1)) > 2) {
ci = upTo[0];
cq = upTo[1];
upTo += 2;
if(upTo >= dmaBuf + ISO14443B_DMA_BUFFER_SIZE) {
if(upTo >= dmaBuf + DMA_BUFFER_SIZE) {
upTo = dmaBuf;
AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) upTo;
AT91C_BASE_PDC_SSC->PDC_RNCR = ISO14443B_DMA_BUFFER_SIZE;
AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE;
}
lastRxCounter -= 2;
if(lastRxCounter <= 0) {
lastRxCounter += ISO14443B_DMA_BUFFER_SIZE;
lastRxCounter += DMA_BUFFER_SIZE;
}
samples += 2;
@ -880,22 +884,6 @@ static void CodeIso14443bAsReader(const uint8_t *cmd, int len)
}
//-----------------------------------------------------------------------------
// Read an ISO 14443B tag. We send it some set of commands, and record the
// responses.
// The command name is misleading, it actually decodes the reponse in HEX
// into the output buffer (read the result using hexsamples, not hisamples)
//
// obsolete function only for test
//-----------------------------------------------------------------------------
void AcquireRawAdcSamplesIso14443b(uint32_t parameter)
{
uint8_t cmd1[] = { 0x05, 0x00, 0x08, 0x39, 0x73 }; // REQB with AFI=0, Request All, N=0
SendRawCommand14443B(sizeof(cmd1),1,1,cmd1);
}
/**
Convenience function to encode, transmit and trace iso 14443b comms
**/
@ -956,7 +944,7 @@ void ReadSTMemoryIso14443b(uint32_t dwLast)
DbpString("No response from tag");
return;
} else {
Dbprintf("Randomly generated UID from tag (+ 2 byte CRC): %x %x %x",
Dbprintf("Randomly generated UID from tag (+ 2 byte CRC): %02x %02x %02x",
Demod.output[0], Demod.output[1], Demod.output[2]);
}
// There is a response, SELECT the uid
@ -981,7 +969,7 @@ void ReadSTMemoryIso14443b(uint32_t dwLast)
}
// Check response from the tag: should be the same UID as the command we just sent:
if (cmd1[1] != Demod.output[0]) {
Dbprintf("Bad response to SELECT from Tag, aborting: %x %x", cmd1[1], Demod.output[0]);
Dbprintf("Bad response to SELECT from Tag, aborting: %02x %02x", cmd1[1], Demod.output[0]);
return;
}
// Tag is now selected,
@ -1000,7 +988,7 @@ void ReadSTMemoryIso14443b(uint32_t dwLast)
// The check the CRC of the answer (use cmd1 as temporary variable):
ComputeCrc14443(CRC_14443_B, Demod.output, 8, &cmd1[2], &cmd1[3]);
if(cmd1[2] != Demod.output[8] || cmd1[3] != Demod.output[9]) {
Dbprintf("CRC Error reading block! - Below: expected, got %x %x",
Dbprintf("CRC Error reading block! Expected: %04x got: %04x",
(cmd1[2]<<8)+cmd1[3], (Demod.output[8]<<8)+Demod.output[9]);
// Do not return;, let's go on... (we should retry, maybe ?)
}
@ -1009,7 +997,7 @@ void ReadSTMemoryIso14443b(uint32_t dwLast)
(Demod.output[3]<<24) + (Demod.output[2]<<16) + (Demod.output[1]<<8) + Demod.output[0]);
// Now loop to read all 16 blocks, address from 0 to last block
Dbprintf("Tag memory dump, block 0 to %d",dwLast);
Dbprintf("Tag memory dump, block 0 to %d", dwLast);
cmd1[0] = 0x08;
i = 0x00;
dwLast++;
@ -1032,12 +1020,12 @@ void ReadSTMemoryIso14443b(uint32_t dwLast)
// The check the CRC of the answer (use cmd1 as temporary variable):
ComputeCrc14443(CRC_14443_B, Demod.output, 4, &cmd1[2], &cmd1[3]);
if(cmd1[2] != Demod.output[4] || cmd1[3] != Demod.output[5]) {
Dbprintf("CRC Error reading block! - Below: expected, got %x %x",
Dbprintf("CRC Error reading block! Expected: %04x got: %04x",
(cmd1[2]<<8)+cmd1[3], (Demod.output[4]<<8)+Demod.output[5]);
// Do not return;, let's go on... (we should retry, maybe ?)
}
// Now print out the memory location:
Dbprintf("Address=%x, Contents=%x, CRC=%x", i,
Dbprintf("Address=%02x, Contents=%08x, CRC=%04x", i,
(Demod.output[3]<<24) + (Demod.output[2]<<16) + (Demod.output[1]<<8) + Demod.output[0],
(Demod.output[4]<<8)+Demod.output[5]);
if (i == 0xff) {
@ -1062,7 +1050,7 @@ void ReadSTMemoryIso14443b(uint32_t dwLast)
* Memory usage for this function, (within BigBuf)
* Last Received command (reader->tag) - MAX_FRAME_SIZE
* Last Received command (tag->reader) - MAX_FRAME_SIZE
* DMA Buffer - ISO14443B_DMA_BUFFER_SIZE
* DMA Buffer - DMA_BUFFER_SIZE
* Demodulated samples received - all the rest
*/
void RAMFUNC SnoopIso14443b(void)
@ -1079,7 +1067,7 @@ void RAMFUNC SnoopIso14443b(void)
set_tracing(TRUE);
// 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(DMA_BUFFER_SIZE);
int lastRxCounter;
int8_t *upTo;
int ci, cq;
@ -1097,7 +1085,7 @@ void RAMFUNC SnoopIso14443b(void)
Dbprintf(" Trace: %i bytes", BigBuf_max_traceLen());
Dbprintf(" Reader -> tag: %i bytes", MAX_FRAME_SIZE);
Dbprintf(" tag -> Reader: %i bytes", MAX_FRAME_SIZE);
Dbprintf(" DMA: %i bytes", ISO14443B_DMA_BUFFER_SIZE);
Dbprintf(" DMA: %i bytes", DMA_BUFFER_SIZE);
// Signal field is off, no reader signal, no tag signal
LEDsoff();
@ -1109,8 +1097,8 @@ void RAMFUNC SnoopIso14443b(void)
// Setup for the DMA.
FpgaSetupSsc();
upTo = dmaBuf;
lastRxCounter = ISO14443B_DMA_BUFFER_SIZE;
FpgaSetupSscDma((uint8_t*) dmaBuf, ISO14443B_DMA_BUFFER_SIZE);
lastRxCounter = DMA_BUFFER_SIZE;
FpgaSetupSscDma((uint8_t*) dmaBuf, DMA_BUFFER_SIZE);
uint8_t parity[MAX_PARITY_SIZE];
bool TagIsActive = FALSE;
@ -1119,7 +1107,7 @@ void RAMFUNC SnoopIso14443b(void)
// And now we loop, receiving samples.
for(;;) {
int behindBy = (lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR) &
(ISO14443B_DMA_BUFFER_SIZE-1);
(DMA_BUFFER_SIZE-1);
if(behindBy > maxBehindBy) {
maxBehindBy = behindBy;
}
@ -1130,14 +1118,14 @@ void RAMFUNC SnoopIso14443b(void)
cq = upTo[1];
upTo += 2;
lastRxCounter -= 2;
if(upTo >= dmaBuf + ISO14443B_DMA_BUFFER_SIZE) {
if(upTo >= dmaBuf + DMA_BUFFER_SIZE) {
upTo = dmaBuf;
lastRxCounter += ISO14443B_DMA_BUFFER_SIZE;
lastRxCounter += DMA_BUFFER_SIZE;
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 = DMA_BUFFER_SIZE;
WDT_HIT();
if(behindBy > (9*ISO14443B_DMA_BUFFER_SIZE/10)) { // TODO: understand whether we can increase/decrease as we want or not?
Dbprintf("blew circular buffer! behindBy=0x%x", behindBy);
if(behindBy > (9*DMA_BUFFER_SIZE/10)) { // TODO: understand whether we can increase/decrease as we want or not?
Dbprintf("blew circular buffer! behindBy=%d", behindBy);
break;
}
if(!tracing) {

View file

@ -25,154 +25,23 @@
static int CmdHelp(const char *Cmd);
int CmdHF14BDemod(const char *Cmd)
{
int i, j, iold;
int isum, qsum;
int outOfWeakAt;
bool negateI, negateQ;
uint8_t data[256];
int dataLen = 0;
// As received, the samples are pairs, correlations against I and Q
// square waves. So estimate angle of initial carrier (or just
// quadrant, actually), and then do the demod.
// First, estimate where the tag starts modulating.
for (i = 0; i < GraphTraceLen; i += 2) {
if (abs(GraphBuffer[i]) + abs(GraphBuffer[i + 1]) > 40) {
break;
}
}
if (i >= GraphTraceLen) {
PrintAndLog("too weak to sync");
return 0;
}
PrintAndLog("out of weak at %d", i);
outOfWeakAt = i;
// Now, estimate the phase in the initial modulation of the tag
isum = 0;
qsum = 0;
for (; i < (outOfWeakAt + 16); i += 2) {
isum += GraphBuffer[i + 0];
qsum += GraphBuffer[i + 1];
}
negateI = (isum < 0);
negateQ = (qsum < 0);
// Turn the correlation pairs into soft decisions on the bit.
j = 0;
for (i = 0; i < GraphTraceLen / 2; i++) {
int si = GraphBuffer[j];
int sq = GraphBuffer[j + 1];
if (negateI) si = -si;
if (negateQ) sq = -sq;
GraphBuffer[i] = si + sq;
j += 2;
}
GraphTraceLen = i;
i = outOfWeakAt / 2;
while (GraphBuffer[i] > 0 && i < GraphTraceLen)
i++;
if (i >= GraphTraceLen) goto demodError;
iold = i;
while (GraphBuffer[i] < 0 && i < GraphTraceLen)
i++;
if (i >= GraphTraceLen) goto demodError;
if ((i - iold) > 23) goto demodError;
PrintAndLog("make it to demod loop");
for (;;) {
iold = i;
while (GraphBuffer[i] >= 0 && i < GraphTraceLen)
i++;
if (i >= GraphTraceLen) goto demodError;
if ((i - iold) > 6) goto demodError;
uint16_t shiftReg = 0;
if (i + 20 >= GraphTraceLen) goto demodError;
for (j = 0; j < 10; j++) {
int soft = GraphBuffer[i] + GraphBuffer[i + 1];
if (abs(soft) < (abs(isum) + abs(qsum)) / 20) {
PrintAndLog("weak bit");
}
shiftReg >>= 1;
if(GraphBuffer[i] + GraphBuffer[i+1] >= 0) {
shiftReg |= 0x200;
}
i+= 2;
}
if ((shiftReg & 0x200) && !(shiftReg & 0x001))
{
// valid data byte, start and stop bits okay
PrintAndLog(" %02x", (shiftReg >> 1) & 0xff);
data[dataLen++] = (shiftReg >> 1) & 0xff;
if (dataLen >= sizeof(data)) {
return 0;
}
} else if (shiftReg == 0x000) {
// this is EOF
break;
} else {
goto demodError;
}
}
uint8_t first, second;
ComputeCrc14443(CRC_14443_B, data, dataLen-2, &first, &second);
PrintAndLog("CRC: %02x %02x (%s)\n", first, second,
(first == data[dataLen-2] && second == data[dataLen-1]) ?
"ok" : "****FAIL****");
RepaintGraphWindow();
return 0;
demodError:
PrintAndLog("demod error");
RepaintGraphWindow();
return 0;
}
int CmdHF14BList(const char *Cmd)
{
PrintAndLog("Deprecated command, use 'hf list 14b' instead");
return 0;
}
int CmdHF14BRead(const char *Cmd)
{
UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443, {strtol(Cmd, NULL, 0), 0, 0}};
SendCommand(&c);
return 0;
}
int CmdHF14Sim(const char *Cmd)
int CmdHF14BSim(const char *Cmd)
{
UsbCommand c={CMD_SIMULATE_TAG_ISO_14443};
SendCommand(&c);
return 0;
}
int CmdHFSimlisten(const char *Cmd)
{
UsbCommand c = {CMD_SIMULATE_TAG_HF_LISTEN};
UsbCommand c={CMD_SIMULATE_TAG_ISO_14443B};
SendCommand(&c);
return 0;
}
int CmdHF14BSnoop(const char *Cmd)
{
UsbCommand c = {CMD_SNOOP_ISO_14443};
UsbCommand c = {CMD_SNOOP_ISO_14443B};
SendCommand(&c);
return 0;
}
@ -387,12 +256,9 @@ int CmdHF14BWrite( const char *Cmd){
static command_t CommandTable[] =
{
{"help", CmdHelp, 1, "This help"},
{"demod", CmdHF14BDemod, 1, "Demodulate ISO14443 Type B from tag"},
{"list", CmdHF14BList, 0, "[Deprecated] List ISO 14443b history"},
{"read", CmdHF14BRead, 0, "Read HF tag (ISO 14443)"},
{"sim", CmdHF14Sim, 0, "Fake ISO 14443 tag"},
{"simlisten", CmdHFSimlisten, 0, "Get HF samples as fake tag"},
{"snoop", CmdHF14BSnoop, 0, "Eavesdrop ISO 14443"},
{"sim", CmdHF14BSim, 0, "Fake ISO 14443B tag"},
{"snoop", CmdHF14BSnoop, 0, "Eavesdrop ISO 14443B"},
{"sri512read", CmdSri512Read, 0, "Read contents of a SRI512 tag"},
{"srix4kread", CmdSrix4kRead, 0, "Read contents of a SRIX4K tag"},
{"raw", CmdHF14BCmdRaw, 0, "Send raw hex data to tag"},

View file

@ -89,7 +89,6 @@ typedef struct {
// For the 13.56 MHz tags
#define CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693 0x0300
#define CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443 0x0301
#define CMD_READ_SRI512_TAG 0x0303
#define CMD_READ_SRIX4K_TAG 0x0304
#define CMD_READER_ISO_15693 0x0310
@ -105,9 +104,8 @@ typedef struct {
#define CMD_SIMULATE_HITAG 0x0371
#define CMD_READER_HITAG 0x0372
#define CMD_SIMULATE_TAG_HF_LISTEN 0x0380
#define CMD_SIMULATE_TAG_ISO_14443 0x0381
#define CMD_SNOOP_ISO_14443 0x0382
#define CMD_SIMULATE_TAG_ISO_14443B 0x0381
#define CMD_SNOOP_ISO_14443B 0x0382
#define CMD_SNOOP_ISO_14443a 0x0383
#define CMD_SIMULATE_TAG_ISO_14443a 0x0384
#define CMD_READER_ISO_14443a 0x0385

View file

@ -59,7 +59,6 @@ local _commands = {
--// For the 13.56 MHz tags
CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693 = 0x0300,
CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443 = 0x0301,
CMD_READ_SRI512_TAG = 0x0303,
CMD_READ_SRIX4K_TAG = 0x0304,
CMD_READER_ISO_15693 = 0x0310,
@ -76,9 +75,8 @@ local _commands = {
CMD_SIMULATE_HITAG = 0x0371,
CMD_READER_HITAG = 0x0372,
CMD_SIMULATE_TAG_HF_LISTEN = 0x0380,
CMD_SIMULATE_TAG_ISO_14443 = 0x0381,
CMD_SNOOP_ISO_14443 = 0x0382,
CMD_SIMULATE_TAG_ISO_14443B = 0x0381,
CMD_SNOOP_ISO_14443B = 0x0382,
CMD_SNOOP_ISO_14443a = 0x0383,
CMD_SIMULATE_TAG_ISO_14443a = 0x0384,
CMD_READER_ISO_14443a = 0x0385,

View file

@ -100,7 +100,6 @@ typedef struct{
// For the 13.56 MHz tags
#define CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693 0x0300
#define CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443 0x0301
#define CMD_READ_SRI512_TAG 0x0303
#define CMD_READ_SRIX4K_TAG 0x0304
#define CMD_ISO_14443B_COMMAND 0x0305
@ -118,9 +117,8 @@ typedef struct{
#define CMD_SIMULATE_HITAG 0x0371
#define CMD_READER_HITAG 0x0372
#define CMD_SIMULATE_TAG_HF_LISTEN 0x0380
#define CMD_SIMULATE_TAG_ISO_14443 0x0381
#define CMD_SNOOP_ISO_14443 0x0382
#define CMD_SIMULATE_TAG_ISO_14443B 0x0381
#define CMD_SNOOP_ISO_14443B 0x0382
#define CMD_SNOOP_ISO_14443a 0x0383
#define CMD_SIMULATE_TAG_ISO_14443a 0x0384
#define CMD_READER_ISO_14443a 0x0385