if(Handle14443bSamplesDemod(ci, cq)) {
gotFrame = TRUE;
- break;
+ break;
- }
}
+ }
if(samples > n || gotFrame) {
break;
}
// 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 ?)
+ // 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;
+ 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]) {
+ 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 ?)
+ // 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;
- }
+ (Demod.output[4]<<8)+Demod.output[5]
+ );
+ if (i == 0xff) break;
i++;
}
}
// 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;
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);
+ break;
}
if(!tracing) {
DbpString("Reached trace limit");
if (!TagIsActive) { // no need to try decoding reader data if the tag is sending
if(Handle14443bUartBit(ci & 0x01)) {
- if(triggered && tracing) {
+ 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();
- /* And also reset the demod code, which might have been */
- /* false-triggered by the commands from the reader. */
- DemodReset();
}
+ /* 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(Handle14443bUartBit(cq & 0x01)) {
- if(triggered && tracing) {
+ 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();
- /* And also reset the demod code, which might have been */
- /* false-triggered by the commands from the reader. */
- DemodReset();
}
+ /* 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();
+ }
ReaderIsActive = (Uart.state > STATE_GOT_FALLING_EDGE_OF_SOF);
}
if(!ReaderIsActive) { // no need to try decoding tag data if the reader is sending - and we cannot afford the time
if(Handle14443bSamplesDemod(ci | 0x01, cq | 0x01)) {
- //Use samples as a time measurement
- if(tracing)
- {
- uint8_t parity[MAX_PARITY_SIZE];
+ //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);
+ LogTrace(Demod.output, Demod.len, samples, samples, parity, FALSE);
- }
- triggered = TRUE;
-
- // And ready to receive another response.
- DemodReset();
}
+ triggered = TRUE;
+
+ // And ready to receive another response.
+ DemodReset();
+ }
TagIsActive = (Demod.state > DEMOD_GOT_FALLING_EDGE_OF_SOF);
}
int CmdHF14BSim(const char *Cmd)
{
- UsbCommand c={CMD_SIMULATE_TAG_ISO_14443B};
- clearCommandBuffer();
+ UsbCommand c={CMD_SIMULATE_TAG_ISO_14443B};
- SendCommand(&c);
- return 0;
+ 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;
+ SendCommand(&c);
+ return 0;
}
/* New command to read the contents of a SRI512 tag
PrintAndLog("Missing data input");
return 0;
}
- if(crc)
- {
- uint8_t first, second;
- ComputeCrc14443(CRC_14443_B, data, datalen, &first, &second);
- data[datalen++] = first;
- data[datalen++] = second;
- }
+
+ return HF14BCmdRaw(reply, &crc, power, data, &datalen, true);
+}
+
+static void print_atqb_resp(uint8_t *data){
+ PrintAndLog (" UID: %s", sprint_hex(data+1,4));
+ PrintAndLog (" App Data: %s", sprint_hex(data+5,4));
+ PrintAndLog (" Protocol: %s", sprint_hex(data+9,3));
+ uint8_t BitRate = data[9];
+ if (!BitRate) PrintAndLog (" Bit Rate: 106 kbit/s only PICC <-> PCD");
+ if (BitRate & 0x10) PrintAndLog (" Bit Rate: 212 kbit/s PICC -> PCD supported");
+ if (BitRate & 0x20) PrintAndLog (" Bit Rate: 424 kbit/s PICC -> PCD supported");
+ if (BitRate & 0x40) PrintAndLog (" Bit Rate: 847 kbit/s PICC -> PCD supported");
+ if (BitRate & 0x01) PrintAndLog (" Bit Rate: 212 kbit/s PICC <- PCD supported");
+ if (BitRate & 0x02) PrintAndLog (" Bit Rate: 424 kbit/s PICC <- PCD supported");
+ if (BitRate & 0x04) PrintAndLog (" Bit Rate: 847 kbit/s PICC <- PCD supported");
+ if (BitRate & 0x80) PrintAndLog (" Same bit rate <-> required");
+
+ uint16_t maxFrame = data[10]>>4;
+ if (maxFrame < 5) maxFrame = 8 * maxFrame + 16;
+ else if (maxFrame == 5) maxFrame = 64;
+ else if (maxFrame == 6) maxFrame = 96;
+ else if (maxFrame == 7) maxFrame = 128;
+ else if (maxFrame == 8) maxFrame = 256;
+ else maxFrame = 257;
+
+ PrintAndLog ("Max Frame Size: %d%s", maxFrame, (maxFrame == 257) ? "+ RFU" : "");
+
+ uint8_t protocolT = data[10] & 0xF;
+ PrintAndLog (" Protocol Type: Protocol is %scompliant with ISO/IEC 14443-4",(protocolT) ? "" : "not " );
+ PrintAndLog ("Frame Wait Int: %d", data[11]>>4);
+ PrintAndLog (" App Data Code: Application is %s",(data[11]&4) ? "Standard" : "Proprietary");
+ PrintAndLog (" Frame Options: NAD is %ssupported",(data[11]&2) ? "" : "not ");
+ PrintAndLog (" Frame Options: CID is %ssupported",(data[11]&1) ? "" : "not ");
+
+ return;
+}
+
+char *get_ST_Chip_Model(uint8_t data){
+ static char model[20];
+ char *retStr = model;
+ memset(model,0, sizeof(model));
+
+ switch (data) {
+ case 0x0: sprintf(retStr, "SRIX4K (Special)"); break;
+ case 0x2: sprintf(retStr, "SR176"); break;
+ case 0x3: sprintf(retStr, "SRIX4K"); break;
+ case 0x4: sprintf(retStr, "SRIX512"); break;
+ case 0x6: sprintf(retStr, "SRI512"); break;
+ case 0x7: sprintf(retStr, "SRI4K"); break;
+ 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?");
- }
- } else {
- PrintAndLog("timeout while waiting for reply.");
- }
- } // if reply
- return 0;
+ }
+
+ crc = false;
+ *datalen = 1;
+ data[0] = 0x0a;
+
+ if (HF14BCmdRaw(true, &crc, false, data, datalen, false)!=0) {
+ if (*datalen > 0) {
+ PrintAndLog ("\n14443-3b tag found:");
+ PrintAndLog ("Unknown tag type answered to a 0x0A command ans:");
+ PrintAndLog ("%s",sprint_hex(data,*datalen));
+ return 1;
+ }
+ }
+
+ crc = false;
+ *datalen = 1;
+ data[0] = 0x0c;
+
+ if (HF14BCmdRaw(true, &crc, false, data, datalen, false)!=0) {
+ if (*datalen > 0) {
+ PrintAndLog ("\n14443-3b tag found:");
+ PrintAndLog ("Unknown tag type answered to a 0x0C command ans:");
+ PrintAndLog ("%s",sprint_hex(data,*datalen));
+ return 1;
+ }
+ }
+
+ return 0;
+
}
-int CmdHF14BWrite( const char *Cmd){
+int HF14BReader(bool verbose){
+ uint8_t data[100];
+ uint8_t datalen = 5;
+
+ // try std 14b (atqb)
+ if (HF14BStdReader(data, &datalen)) return 1;
+
+ // try st 14b
+ if (HF14B_ST_Reader(data, &datalen)) return 1;
+
+ // try unknown 14b read commands (to be identified later)
+ // could be read of calypso, CEPAS, moneo, or pico pass.
+ if (HF14B_Other_Reader(data, &datalen)) return 1;
+
+ if (verbose) PrintAndLog("no 14443B tag found");
+ return 0;
+}
+
+int CmdHF14BReader(const char *Cmd){
+ return HF14BReader(true);
+}
+int CmdHF14BWrite( const char *Cmd){
/*
* For SRIX4K blocks 00 - 7F
* hf 14b raw -c -p 09 $srix4kwblock $srix4kwdata
static command_t CommandTable[] =
{
- {"help", CmdHelp, 1, "This help"},
- {"list", CmdHF14BList, 0, "[Deprecated] List ISO 14443b history"},
+ {"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"},
- {"write", CmdHF14BWrite, 0, "Write data to a SRI512 | SRIX4K tag"},
- {NULL, NULL, 0, NULL}
+ {"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"},
+ {"write", CmdHF14BWrite, 0, "Write data to a SRI512 | SRIX4K tag"},
+ {NULL, NULL, 0, NULL}
};
int CmdHF14B(const char *Cmd)