#include "iso14443crc.h"
#define RECEIVE_SAMPLES_TIMEOUT 2000
+#define ISO14443B_DMA_BUFFER_SIZE 256
//=============================================================================
// An ISO 14443 Type B tag. We listen for commands from the reader, using
Uart.posCnt = 0;
Uart.state = STATE_AWAITING_START_BIT;
}
- } else if(Uart.shiftReg == 0x000) {
+ } else if (Uart.shiftReg == 0x000) {
// this is an EOF byte
LED_A_OFF(); // Finished receiving
Uart.state = STATE_UNSYNCD;
} else {
// this is an error
LED_A_OFF();
- Uart.state = STATE_UNSYNCD;
+ Uart.state = STATE_UNSYNCD;
}
}
break;
{
int v;
- // The soft decision on the bit uses an estimate of just the
- // quadrant of the reference angle, not the exact angle.
+// The soft decision on the bit uses an estimate of just the
+// quadrant of the reference angle, not the exact angle.
#define MAKE_SOFT_DECISION() { \
if(Demod.sumI > 0) { \
v = ci; \
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(DMA_BUFFER_SIZE);
+ int8_t *dmaBuf = (int8_t*) BigBuf_malloc(ISO14443B_DMA_BUFFER_SIZE);
// Set up the demodulator for tag -> reader responses.
DemodInit(receivedResponse);
// Setup and start DMA.
- FpgaSetupSscDma((uint8_t*) dmaBuf, DMA_BUFFER_SIZE);
+ FpgaSetupSscDma((uint8_t*) dmaBuf, ISO14443B_DMA_BUFFER_SIZE);
int8_t *upTo = dmaBuf;
- lastRxCounter = DMA_BUFFER_SIZE;
+ lastRxCounter = ISO14443B_DMA_BUFFER_SIZE;
// Signal field is ON with the appropriate LED:
LED_D_ON();
int behindBy = lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR;
if(behindBy > max) max = behindBy;
- while(((lastRxCounter-AT91C_BASE_PDC_SSC->PDC_RCR) & (DMA_BUFFER_SIZE-1)) > 2) {
+ while(((lastRxCounter-AT91C_BASE_PDC_SSC->PDC_RCR) & (ISO14443B_DMA_BUFFER_SIZE-1)) > 2) {
ci = upTo[0];
cq = upTo[1];
upTo += 2;
- if(upTo >= dmaBuf + DMA_BUFFER_SIZE) {
+ if(upTo >= dmaBuf + ISO14443B_DMA_BUFFER_SIZE) {
upTo = dmaBuf;
AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) upTo;
- AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE;
+ AT91C_BASE_PDC_SSC->PDC_RNCR = ISO14443B_DMA_BUFFER_SIZE;
}
lastRxCounter -= 2;
if(lastRxCounter <= 0) {
- lastRxCounter += DMA_BUFFER_SIZE;
+ lastRxCounter += ISO14443B_DMA_BUFFER_SIZE;
}
samples += 2;
if(Handle14443bSamplesDemod(ci, cq)) {
gotFrame = TRUE;
- break;
+ break;
}
}
//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);
}
}
TransmitFor14443b();
if (tracing) {
uint8_t parity[MAX_PARITY_SIZE];
- GetParity(cmd, len, parity);
LogTrace(cmd,len, 0, 0, parity, TRUE);
}
}
SpinDelay(200);
// First command: wake up the tag using the INITIATE command
- uint8_t cmd1[] = { 0x06, 0x00, 0x97, 0x5b};
-
+ uint8_t cmd1[] = {0x06, 0x00, 0x97, 0x5b};
CodeAndTransmit14443bAsReader(cmd1, sizeof(cmd1));
-// LED_A_ON();
GetSamplesFor14443bDemod(RECEIVE_SAMPLES_TIMEOUT, TRUE);
-// LED_A_OFF();
if (Demod.len == 0) {
DbpString("No response from tag");
return;
} else {
- Dbprintf("Randomly generated UID from tag (+ 2 byte CRC): %02x %02x %02x",
- Demod.output[0], Demod.output[1],Demod.output[2]);
+ Dbprintf("Randomly generated Chip ID (+ 2 byte CRC): %02x %02x %02x",
+ Demod.output[0], Demod.output[1], Demod.output[2]);
}
+
// There is a response, SELECT the uid
DbpString("Now SELECT tag:");
cmd1[0] = 0x0E; // 0x0E is SELECT
cmd1[1] = Demod.output[0];
ComputeCrc14443(CRC_14443_B, cmd1, 2, &cmd1[2], &cmd1[3]);
CodeAndTransmit14443bAsReader(cmd1, sizeof(cmd1));
-
-// LED_A_ON();
GetSamplesFor14443bDemod(RECEIVE_SAMPLES_TIMEOUT, TRUE);
-// LED_A_OFF();
if (Demod.len != 3) {
Dbprintf("Expected 3 bytes from tag, got %d", Demod.len);
return;
Dbprintf("Bad response to SELECT from Tag, aborting: %02x %02x", cmd1[1], Demod.output[0]);
return;
}
+
// Tag is now selected,
// First get the tag's UID:
cmd1[0] = 0x0B;
ComputeCrc14443(CRC_14443_B, cmd1, 1 , &cmd1[1], &cmd1[2]);
CodeAndTransmit14443bAsReader(cmd1, 3); // Only first three bytes for this one
-
-// LED_A_ON();
GetSamplesFor14443bDemod(RECEIVE_SAMPLES_TIMEOUT, TRUE);
-// LED_A_OFF();
if (Demod.len != 10) {
Dbprintf("Expected 10 bytes from tag, got %d", Demod.len);
return;
}
// 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]) {
+ if(cmd1[2] != Demod.output[8] || cmd1[3] != Demod.output[9]) {
Dbprintf("CRC Error reading block! Expected: %04x got: %04x",
- (cmd1[2]<<8)+cmd1[3],
- (Demod.output[8]<<8)+Demod.output[9]
- );
+ (cmd1[2]<<8)+cmd1[3], (Demod.output[8]<<8)+Demod.output[9]);
// Do not return;, let's go on... (we should retry, maybe ?)
}
Dbprintf("Tag UID (64 bits): %08x %08x",
- (Demod.output[7]<<24) + (Demod.output[6]<<16) + (Demod.output[5]<<8) + Demod.output[4],
- (Demod.output[3]<<24) + (Demod.output[2]<<16) + (Demod.output[1]<<8) + Demod.output[0]);
+ (Demod.output[7]<<24) + (Demod.output[6]<<16) + (Demod.output[5]<<8) + Demod.output[4],
+ (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++;
cmd1[1] = i;
ComputeCrc14443(CRC_14443_B, cmd1, 2, &cmd1[2], &cmd1[3]);
CodeAndTransmit14443bAsReader(cmd1, sizeof(cmd1));
-
-// LED_A_ON();
GetSamplesFor14443bDemod(RECEIVE_SAMPLES_TIMEOUT, TRUE);
-// LED_A_OFF();
if (Demod.len != 6) { // Check if we got an answer from the tag
DbpString("Expected 6 bytes from tag, got less...");
return;
// 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! Expected: %04x got: %04x",
- (cmd1[2]<<8)+cmd1[3],
- (Demod.output[4]<<8)+Demod.output[5]
- );
+ 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=%02x, Contents=%08x, CRC=%04x", i,
- (Demod.output[3]<<24) + (Demod.output[2]<<16) + (Demod.output[1]<<8) + Demod.output[0],
+ (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) break;
* 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 - DMA_BUFFER_SIZE
+ * DMA Buffer - ISO14443B_DMA_BUFFER_SIZE
* Demodulated samples received - all the rest
*/
void RAMFUNC SnoopIso14443b(void)
set_tracing(TRUE);
// The DMA buffer, used to stream samples from the FPGA
- int8_t *dmaBuf = (int8_t*) BigBuf_malloc(DMA_BUFFER_SIZE);
+ int8_t *dmaBuf = (int8_t*) BigBuf_malloc(ISO14443B_DMA_BUFFER_SIZE);
int lastRxCounter;
int8_t *upTo;
int ci, cq;
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", DMA_BUFFER_SIZE);
+ Dbprintf(" DMA: %i bytes", ISO14443B_DMA_BUFFER_SIZE);
// Signal field is off, no reader signal, no tag signal
LEDsoff();
// Setup for the DMA.
FpgaSetupSsc();
upTo = dmaBuf;
- lastRxCounter = DMA_BUFFER_SIZE;
- FpgaSetupSscDma((uint8_t*) dmaBuf, DMA_BUFFER_SIZE);
+ lastRxCounter = ISO14443B_DMA_BUFFER_SIZE;
+ FpgaSetupSscDma((uint8_t*) dmaBuf, ISO14443B_DMA_BUFFER_SIZE);
uint8_t parity[MAX_PARITY_SIZE];
+
+ bool TagIsActive = FALSE;
+ bool ReaderIsActive = FALSE;
bool TagIsActive = FALSE;
bool ReaderIsActive = FALSE;
// And now we loop, receiving samples.
for(;;) {
int behindBy = (lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR) &
- (DMA_BUFFER_SIZE-1);
+ (ISO14443B_DMA_BUFFER_SIZE-1);
if(behindBy > maxBehindBy) {
maxBehindBy = behindBy;
}
cq = upTo[1];
upTo += 2;
lastRxCounter -= 2;
- if(upTo >= dmaBuf + DMA_BUFFER_SIZE) {
+ if(upTo >= dmaBuf + ISO14443B_DMA_BUFFER_SIZE) {
upTo = dmaBuf;
- lastRxCounter += DMA_BUFFER_SIZE;
+ lastRxCounter += ISO14443B_DMA_BUFFER_SIZE;
AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dmaBuf;
- AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE;
+ AT91C_BASE_PDC_SSC->PDC_RNCR = ISO14443B_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=%d", behindBy);
+ break;
WDT_HIT();
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);
if (!TagIsActive) { // no need to try decoding reader data if the tag is sending
if(Handle14443bUartBit(ci & 0x01)) {
if(triggered && tracing) {
- //GetParity(Uart.output, Uart.byteCnt, parity);
- LogTrace(Uart.output,Uart.byteCnt,samples, samples,parity,TRUE);
+ LogTrace(Uart.output, Uart.byteCnt, samples, samples, parity, TRUE);
}
/* And ready to receive another command. */
UartReset();
}
if(Handle14443bUartBit(cq & 0x01)) {
if(triggered && tracing) {
- //GetParity(Uart.output, Uart.byteCnt, parity);
- LogTrace(Uart.output,Uart.byteCnt,samples, samples, parity, TRUE);
+ LogTrace(Uart.output, Uart.byteCnt, samples, samples, parity, TRUE);
}
/* And ready to receive another command. */
UartReset();
if(tracing)
{
uint8_t parity[MAX_PARITY_SIZE];
- //GetParity(Demod.output, Demod.len, parity);
- LogTrace(Demod.output, Demod.len,samples, samples, parity, FALSE);
+ LogTrace(Demod.output, Demod.len, samples, samples, parity, FALSE);
}
triggered = TRUE;
SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
FpgaSetupSsc();
- set_tracing(TRUE);
+ set_tracing(TRUE);
-/* if(!powerfield) {
- // Make sure that we start from off, since the tags are stateful;
- // confusing things will happen if we don't reset them between reads.
- FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
- LED_D_OFF();
- SpinDelay(200);
- }
- */
-
- // if(!GETBIT(GPIO_LED_D)) { // if field is off
- // FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ);
- // // Signal field is on with the appropriate LED
- // LED_D_ON();
- // SpinDelay(200);
- // }
-
CodeAndTransmit14443bAsReader(data, datalen);
if(recv) {
GetSamplesFor14443bDemod(RECEIVE_SAMPLES_TIMEOUT, TRUE);
- uint16_t iLen = MIN(Demod.len,USB_CMD_DATA_SIZE);
- cmd_send(CMD_ACK,iLen,0,0,Demod.output,iLen);
+ uint16_t iLen = MIN(Demod.len, USB_CMD_DATA_SIZE);
+ cmd_send(CMD_ACK, iLen, 0, 0, Demod.output, iLen);
}
if(!powerfield) {
int CmdHF14BSim(const char *Cmd)
{
- UsbCommand c={CMD_SIMULATE_TAG_ISO_14443B};
- clearCommandBuffer();
+ UsbCommand c={CMD_SIMULATE_TAG_ISO_14443B};
SendCommand(&c);
return 0;
}
int CmdHF14BSnoop(const char *Cmd)
{
- UsbCommand c = {CMD_SNOOP_ISO_14443B};
- clearCommandBuffer();
+ UsbCommand c = {CMD_SNOOP_ISO_14443B};
SendCommand(&c);
return 0;
}
case 0xC: sprintf(retStr, "SRT512"); break;
default: sprintf(retStr, "Unknown"); break;
}
- return retStr;
-}
-
-static void print_st_info(uint8_t *data){
- //uid = first 8 bytes in data
- PrintAndLog(" UID: %s", sprint_hex(SwapEndian64(data,8,8),8));
- PrintAndLog(" MFG: %02X, %s", data[6], getTagInfo(data[6]));
- PrintAndLog("Chip: %02X, %s", data[5]>>2, get_ST_Chip_Model(data[5]>>2));
- return;
-}
-
-int HF14BStdReader(uint8_t *data, uint8_t *datalen){
-
- //05 00 00 = find one tag in field
- //1d xx xx xx xx 20 00 08 01 00 = attrib xx=crc
- //a3 = ? (resp 03 e2 c2)
- //02 = ? (resp 02 6a d3)
- // 022b (resp 02 67 00 [29 5b])
- // 0200a40400 (resp 02 67 00 [29 5b])
- // 0200a4040c07a0000002480300 (resp 02 67 00 [29 5b])
- // 0200a4040c07a0000002480200 (resp 02 67 00 [29 5b])
- // 0200a4040006a0000000010100 (resp 02 6a 82 [4b 4c])
- // 0200a4040c09d27600002545500200 (resp 02 67 00 [29 5b])
- // 0200a404000cd2760001354b414e4d30310000 (resp 02 6a 82 [4b 4c])
- // 0200a404000ca000000063504b43532d313500 (resp 02 6a 82 [4b 4c])
- // 0200a4040010a000000018300301000000000000000000 (resp 02 6a 82 [4b 4c])
- //03 = ? (resp 03 [e3 c2])
- //c2 = ? (resp c2 [66 15])
- //b2 = ? (resp a3 [e9 67])
- bool crc = true;
- *datalen = 3;
- //std read cmd
- data[0] = 0x05;
- data[1] = 0x00;
- data[2] = 0x00;
-
- if (HF14BCmdRaw(true, &crc, false, data, datalen, false)==0) return 0;
-
- if (data[0] != 0x50 || *datalen != 14 || !crc) return 0;
-
- PrintAndLog ("\n14443-3b tag found:");
- print_atqb_resp(data);
-
- return 1;
+
+ c.arg[0] = datalen;
+ c.arg[1] = reply;
+ c.arg[2] = power;
+ memcpy(c.d.asBytes,data,datalen);
+
+ SendCommand(&c);
+
+ if (reply) {
+ if (WaitForResponseTimeout(CMD_ACK,&resp,1000)) {
+ recv = resp.d.asBytes;
+ PrintAndLog("received %i octets",resp.arg[0]);
+ if(resp.arg[0] == 0)
+ return 0;
+ hexout = (char *)malloc(resp.arg[0] * 3 + 1);
+ if (hexout != NULL) {
+ uint8_t first, second;
+ for (int i = 0; i < resp.arg[0]; i++) { // data in hex
+ sprintf(&hexout[i * 3], "%02X ", recv[i]);
}
-
-int HF14B_ST_Reader(uint8_t *data, uint8_t *datalen){
- bool crc = true;
- *datalen = 2;
- //wake cmd
- data[0] = 0x06;
- data[1] = 0x00;
-
- //leave power on
- // verbose on for now for testing - turn off when functional
- if (HF14BCmdRaw(true, &crc, true, data, datalen, false)==0) return rawClose();
-
- if (*datalen != 3 || !crc) return rawClose();
-
- uint8_t chipID = data[0];
- // select
- data[0] = 0x0E;
- data[1] = chipID;
- *datalen = 2;
-
- //leave power on
- // verbose on for now for testing - turn off when functional
- if (HF14BCmdRaw(true, &crc, true, data, datalen, false)==0) return rawClose();
-
- if (*datalen != 3 || !crc || data[0] != chipID) return rawClose();
-
- // get uid
- data[0] = 0x0B;
- *datalen = 1;
-
- //power off
- // verbose on for now for testing - turn off when functional
- if (HF14BCmdRaw(true, &crc, true, data, datalen, false)==0) return 0;
- rawClose();
- if (*datalen != 10 || !crc) return 0;
-
- PrintAndLog("\n14443-3b ST tag found:");
- print_st_info(data);
- return 1;
-}
-
-// test for other 14b type tags (mimic another reader - don't have tags to identify)
-int HF14B_Other_Reader(uint8_t *data, uint8_t *datalen){
- bool crc = true;
- *datalen = 4;
- //std read cmd
- data[0] = 0x00;
- data[1] = 0x0b;
- data[2] = 0x3f;
- data[3] = 0x80;
-
- if (HF14BCmdRaw(true, &crc, false, data, datalen, false)!=0) {
- if (*datalen > 2 || !crc) {
- PrintAndLog ("\n14443-3b tag found:");
- PrintAndLog ("Unknown tag type answered to a 0x000b3f80 command ans:");
- PrintAndLog ("%s",sprint_hex(data,*datalen));
- return 1;
- }
+ PrintAndLog("%s", hexout);
+ free(hexout);
+ if (resp.arg[0] > 2) {
+ ComputeCrc14443(CRC_14443_B, recv, resp.arg[0]-2, &first, &second);
+ if(recv[resp.arg[0]-2]==first && recv[resp.arg[0]-1]==second) {
+ PrintAndLog("CRC OK");
+ } else {
+ PrintAndLog("CRC failed");
+ }
+ }
+ } else {
+ PrintAndLog("malloc failed your client has low memory?");
}
crc = false;
{
{"help", CmdHelp, 1, "This help"},
{"list", CmdHF14BList, 0, "[Deprecated] List ISO 14443b history"},
- {"reader", CmdHF14BReader, 0, "Find 14b tag (HF ISO 14443b)"},
- {"sim", CmdHF14BSim, 0, "Fake ISO 14443B tag"},
-
- {"snoop", CmdHF14BSnoop, 0, "Eavesdrop ISO 14443B"},
+ {"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"},