pace_version_info_t *pace_info)
{
size_t index = 0;
-
+
while (index <= length - 2) {
// determine type of element
// SET or SEQUENCE
index += 2 + data[index + 1];
}
}
-
+
// TODO: We should check whether we reached the end in error, but for that
// we need a better parser (e.g. with states like IN_SET or IN_PACE_INFO)
return 0;
// we reserve 262 bytes here just to be safe (256-byte APDU + SW + ISO frame)
uint8_t response_apdu[262];
int rapdu_length = 0;
-
+
// select the file EF.CardAccess
rapdu_length = iso14_apdu((uint8_t *)apdu_select_binary_cardaccess,
sizeof(apdu_select_binary_cardaccess),
Dbprintf("epa - no select cardaccess");
return -1;
}
-
+
// read the file
rapdu_length = iso14_apdu((uint8_t *)apdu_read_binary,
sizeof(apdu_read_binary),
Dbprintf("epa - no read cardaccess");
return -1;
}
-
+
// copy the content into the buffer
// length of data available: apdu_length - 4 (ISO frame) - 2 (SW)
size_t to_copy = rapdu_length - 6;
{
// power down the field
EPA_Finish();
-
+
// send the USB packet
cmd_send(CMD_ACK,step,func_return,0,0,0);
}
// set up communication
func_return = EPA_Setup();
- if (func_return != 0) {
+ if (func_return != 0) {
EPA_PACE_Collect_Nonce_Abort(1, func_return);
return;
}
EPA_PACE_Collect_Nonce_Abort(3, func_return);
return;
}
-
+
// initiate the PACE protocol
// use the CAN for the password since that doesn't change
func_return = EPA_PACE_MSE_Set_AT(pace_version_info, 2);
-
+
// now get the nonce
uint8_t nonce[256] = {0};
uint8_t requested_size = (uint8_t)c->arg[0];
EPA_PACE_Collect_Nonce_Abort(4, func_return);
return;
}
-
- // all done, return
+
+ // all done, return
EPA_Finish();
-
+
// save received information
cmd_send(CMD_ACK,0,func_return,0,nonce,func_return);
}
sizeof(apdu_general_authenticate_pace_get_nonce));
// append Le (requested length + 2 due to tag/length taking 2 bytes) in RAPDU
apdu[sizeof(apdu_general_authenticate_pace_get_nonce)] = requested_length + 4;
-
+
// send it
uint8_t response_apdu[262];
int send_return = iso14_apdu(apdu,
{
return -1;
}
-
+
// if there is no nonce in the RAPDU, return here
if (send_return < 10)
{
}
// copy the nonce
memcpy(nonce, response_apdu + 6, nonce_length);
-
+
return nonce_length;
}
#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;
if (Uart.byteCnt != 0) {
- return TRUE;
+ return TRUE;
}
} else {
// this is an error
LED_A_OFF();
- Uart.state = STATE_UNSYNCD;
+ Uart.state = STATE_UNSYNCD;
}
}
break;
for(;;) {
if(!GetIso14443bCommandFromReader(receivedCmd, &len)) {
- Dbprintf("button pressed, received %d commands", cmdsRecvd);
- break;
+ Dbprintf("button pressed, received %d commands", cmdsRecvd);
+ break;
}
if (tracing) {
{
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; \
Demod.sumI = ci;
Demod.sumQ = cq;
Demod.posCount = 1;
- }
+ }
break;
case DEMOD_PHASE_REF_TRAINING:
if (v > SUBCARRIER_DETECT_THRESHOLD) {
// set the reference phase (will code a logic '1') by averaging over 32 1/fs.
// note: synchronization time > 80 1/fs
- Demod.sumI += ci;
- Demod.sumQ += cq;
+ Demod.sumI += ci;
+ Demod.sumQ += cq;
Demod.posCount++;
} else { // subcarrier lost
- Demod.state = DEMOD_UNSYNCD;
+ Demod.state = DEMOD_UNSYNCD;
}
} else {
- Demod.state = DEMOD_AWAITING_FALLING_EDGE_OF_SOF;
+ Demod.state = DEMOD_AWAITING_FALLING_EDGE_OF_SOF;
}
break;
LED_C_OFF();
if(s == 0x000) {
// This is EOF (start, stop and all data bits == '0'
- return TRUE;
+ return TRUE;
}
}
}
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;
- }
}
+ }
if(samples > n || gotFrame) {
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 ?)
+ // 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++;
for (;;) {
- if (i == dwLast) {
+ if (i == dwLast) {
DbpString("System area block (0xff):");
i = 0xff;
}
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++;
}
}
* 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);
+ 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);
}
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) {
AcquireTiType();
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
- DbpString("Now use tiread to check");
+ DbpString("Now use 'lf ti read' to check");
}
void SimulateTagLowFrequency(int period, int gap, int ledcontrol)
{
uint8_t *dest = BigBuf_get_addr();
//const size_t sizeOfBigBuff = BigBuf_max_traceLen();
- size_t size;
+ size_t size = 0;
uint32_t hi2=0, hi=0, lo=0;
int idx=0;
// Configure to go in 125Khz listen mode
if (errCnt<0) continue;
- errCnt = Em410xDecode(dest, &size, &idx, &hi, &lo);
- if (errCnt){
- if (size>64){
- Dbprintf("EM XL TAG ID: %06x%08x%08x - (%05d_%03d_%08d)",
- hi,
- (uint32_t)(lo>>32),
- (uint32_t)lo,
- (uint32_t)(lo&0xFFFF),
- (uint32_t)((lo>>16LL) & 0xFF),
- (uint32_t)(lo & 0xFFFFFF));
- } else {
- Dbprintf("EM TAG ID: %02x%08x - (%05d_%03d_%08d)",
- (uint32_t)(lo>>32),
- (uint32_t)lo,
- (uint32_t)(lo&0xFFFF),
- (uint32_t)((lo>>16LL) & 0xFF),
- (uint32_t)(lo & 0xFFFFFF));
- }
+ errCnt = Em410xDecode(dest, &size, &idx, &hi, &lo);
+ if (errCnt){
+ if (size>64){
+ Dbprintf("EM XL TAG ID: %06x%08x%08x - (%05d_%03d_%08d)",
+ hi,
+ (uint32_t)(lo>>32),
+ (uint32_t)lo,
+ (uint32_t)(lo&0xFFFF),
+ (uint32_t)((lo>>16LL) & 0xFF),
+ (uint32_t)(lo & 0xFFFFFF));
+ } else {
+ Dbprintf("EM TAG ID: %02x%08x - (%05d_%03d_%08d)",
+ (uint32_t)(lo>>32),
+ (uint32_t)lo,
+ (uint32_t)(lo&0xFFFF),
+ (uint32_t)((lo>>16LL) & 0xFF),
+ (uint32_t)(lo & 0xFFFFFF));
+ }
if (findone){
if (ledcontrol) LED_A_OFF();
uint8_t version=0;
uint8_t facilitycode=0;
uint16_t number=0;
+ uint8_t crc = 0;
+ uint16_t calccrc = 0;
// Configure to go in 125Khz listen mode
LFSetupFPGAForADC(95, true);
WDT_HIT();
idx = IOdemodFSK(dest, BigBuf_max_traceLen());
if (idx<0) continue;
- //valid tag found
-
- //Index map
- //0 10 20 30 40 50 60
- //| | | | | | |
- //01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23
- //-----------------------------------------------------------------------------
- //00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 ???????? 11
- //
- //XSF(version)facility:codeone+codetwo
- //Handle the data
- if(findone){ //only print binary if we are doing one
- Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx], dest[idx+1], dest[idx+2],dest[idx+3],dest[idx+4],dest[idx+5],dest[idx+6],dest[idx+7],dest[idx+8]);
- Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+9], dest[idx+10],dest[idx+11],dest[idx+12],dest[idx+13],dest[idx+14],dest[idx+15],dest[idx+16],dest[idx+17]);
- Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+18],dest[idx+19],dest[idx+20],dest[idx+21],dest[idx+22],dest[idx+23],dest[idx+24],dest[idx+25],dest[idx+26]);
- Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+27],dest[idx+28],dest[idx+29],dest[idx+30],dest[idx+31],dest[idx+32],dest[idx+33],dest[idx+34],dest[idx+35]);
- Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+36],dest[idx+37],dest[idx+38],dest[idx+39],dest[idx+40],dest[idx+41],dest[idx+42],dest[idx+43],dest[idx+44]);
- Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+45],dest[idx+46],dest[idx+47],dest[idx+48],dest[idx+49],dest[idx+50],dest[idx+51],dest[idx+52],dest[idx+53]);
- Dbprintf("%d%d%d%d%d%d%d%d %d%d",dest[idx+54],dest[idx+55],dest[idx+56],dest[idx+57],dest[idx+58],dest[idx+59],dest[idx+60],dest[idx+61],dest[idx+62],dest[idx+63]);
- }
- code = bytebits_to_byte(dest+idx,32);
- code2 = bytebits_to_byte(dest+idx+32,32);
- version = bytebits_to_byte(dest+idx+27,8); //14,4
+ //valid tag found
+
+ //Index map
+ //0 10 20 30 40 50 60
+ //| | | | | | |
+ //01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23
+ //-----------------------------------------------------------------------------
+ //00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 checksum 11
+ //
+ //Checksum:
+ //00000000 0 11110000 1 11100000 1 00000001 1 00000011 1 10110110 1 01110101 11
+ //preamble F0 E0 01 03 B6 75
+ // How to calc checksum,
+ // http://www.proxmark.org/forum/viewtopic.php?id=364&p=6
+ // F0 + E0 + 01 + 03 + B6 = 28A
+ // 28A & FF = 8A
+ // FF - 8A = 75
+ // Checksum: 0x75
+ //XSF(version)facility:codeone+codetwo
+ //Handle the data
+ if(findone){ //only print binary if we are doing one
+ Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx], dest[idx+1], dest[idx+2],dest[idx+3],dest[idx+4],dest[idx+5],dest[idx+6],dest[idx+7],dest[idx+8]);
+ Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+9], dest[idx+10],dest[idx+11],dest[idx+12],dest[idx+13],dest[idx+14],dest[idx+15],dest[idx+16],dest[idx+17]);
+ Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+18],dest[idx+19],dest[idx+20],dest[idx+21],dest[idx+22],dest[idx+23],dest[idx+24],dest[idx+25],dest[idx+26]);
+ Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+27],dest[idx+28],dest[idx+29],dest[idx+30],dest[idx+31],dest[idx+32],dest[idx+33],dest[idx+34],dest[idx+35]);
+ Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+36],dest[idx+37],dest[idx+38],dest[idx+39],dest[idx+40],dest[idx+41],dest[idx+42],dest[idx+43],dest[idx+44]);
+ Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+45],dest[idx+46],dest[idx+47],dest[idx+48],dest[idx+49],dest[idx+50],dest[idx+51],dest[idx+52],dest[idx+53]);
+ Dbprintf("%d%d%d%d%d%d%d%d %d%d",dest[idx+54],dest[idx+55],dest[idx+56],dest[idx+57],dest[idx+58],dest[idx+59],dest[idx+60],dest[idx+61],dest[idx+62],dest[idx+63]);
+ }
+ code = bytebits_to_byte(dest+idx,32);
+ code2 = bytebits_to_byte(dest+idx+32,32);
+ version = bytebits_to_byte(dest+idx+27,8); //14,4
facilitycode = bytebits_to_byte(dest+idx+18,8);
- number = (bytebits_to_byte(dest+idx+36,8)<<8)|(bytebits_to_byte(dest+idx+45,8)); //36,9
-
- Dbprintf("XSF(%02d)%02x:%05d (%08x%08x)",version,facilitycode,number,code,code2);
- // if we're only looking for one tag
- if (findone){
- if (ledcontrol) LED_A_OFF();
- //LED_A_OFF();
- *high=code;
- *low=code2;
- return;
- }
- code=code2=0;
- version=facilitycode=0;
- number=0;
- idx=0;
+ number = (bytebits_to_byte(dest+idx+36,8)<<8)|(bytebits_to_byte(dest+idx+45,8)); //36,9
+
+ crc = bytebits_to_byte(dest+idx+54,8);
+ for (uint8_t i=1; i<6; ++i)
+ calccrc += bytebits_to_byte(dest+idx+9*i,8);
+ calccrc &= 0xff;
+ calccrc = 0xff - calccrc;
+
+ char *crcStr = (crc == calccrc) ? "ok":"!crc";
+
+ Dbprintf("IO Prox XSF(%02d)%02x:%05d (%08x%08x) [%02x %s]",version,facilitycode,number,code,code2, crc, crcStr);
+ // if we're only looking for one tag
+ if (findone){
+ if (ledcontrol) LED_A_OFF();
+ //LED_A_OFF();
+ *high=code;
+ *low=code2;
+ return;
+ }
+ code=code2=0;
+ version=facilitycode=0;
+ number=0;
+ idx=0;
WDT_HIT();
}
* To compensate antenna falling times shorten the write times
* and enlarge the gap ones.
*/
- #define START_GAP 31*8 // was 250 // SPEC: 8 - 50fc [15fc]
- #define WRITE_GAP 20*8 // was 160 // SPEC: 8 - 20fc [10fc]
- #define WRITE_0 18*8 // was 144 // SPEC: 16 - 32fc [24fc] 192
- #define WRITE_1 50*8 // was 400 // SPEC: 48 - 64fc [56fc] 432 for T55x7; 448 for E5550
+ #define START_GAP 31*8 // was 250 // SPEC: 1*8 to 50*8 - typ 15*8 (or 15fc)
+ #define WRITE_GAP 20*8 // was 160 // SPEC: 1*8 to 20*8 - typ 10*8 (or 10fc)
+ #define WRITE_0 18*8 // was 144 // SPEC: 16*8 to 32*8 - typ 24*8 (or 24fc)
+ #define WRITE_1 50*8 // was 400 // SPEC: 48*8 to 64*8 - typ 56*8 (or 56fc) 432 for T55x7; 448 for E5550
+// VALUES TAKEN FROM EM4x function: SendForward
+// START_GAP = 440; (55*8) cycles at 125Khz (8us = 1cycle)
+// WRITE_GAP = 128; (16*8)
+// WRITE_1 = 256 32*8; (32*8)
+
+// These timings work for 4469/4269/4305 (with the 55*8 above)
+// WRITE_0 = 23*8 , 9*8 SpinDelayUs(23*8);
+
+// Sam7s has several timers, we will use the source TIMER_CLOCK1 (aka AT91C_TC_CLKS_TIMER_DIV1_CLOCK)
+// TIMER_CLOCK1 = MCK/2, MCK is running at 48 MHz, Timer is running at 48/2 = 24 MHz
+// Hitag units (T0) have duration of 8 microseconds (us), which is 1/125000 per second (carrier)
+// T0 = TIMER_CLOCK1 / 125000 = 192
+// 1 Cycle = 8 microseconds(us)
+
#define T55xx_SAMPLES_SIZE 12000 // 32 x 32 x 10 (32 bit times numofblock (7), times clock skip..)
// Write one bit to card
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
- if (bit == 0)
+ if (!bit)
SpinDelayUs(WRITE_0);
else
SpinDelayUs(WRITE_1);
#define max(x,y) ( x<y ? y:x)
int DemodPCF7931(uint8_t **outBlocks) {
- uint8_t BitStream[256];
- uint8_t Blocks[8][16];
- uint8_t *GraphBuffer = BigBuf_get_addr();
+
+ uint8_t bits[256] = {0x00};
+ uint8_t blocks[8][16];
+ uint8_t *dest = BigBuf_get_addr();
+
int GraphTraceLen = BigBuf_max_traceLen();
+ if ( GraphTraceLen > 18000 )
+ GraphTraceLen = 18000;
+
+
int i, j, lastval, bitidx, half_switch;
int clock = 64;
int tolerance = clock / 8;
uint8_t dir;
LFSetupFPGAForADC(95, true);
- DoAcquisition_default(0, 0);
-
+ DoAcquisition_default(0, true);
lmin = 64;
lmax = 192;
i = 2;
/* Find first local max/min */
- if(GraphBuffer[1] > GraphBuffer[0]) {
+ if(dest[1] > dest[0]) {
while(i < GraphTraceLen) {
- if( !(GraphBuffer[i] > GraphBuffer[i-1]) && GraphBuffer[i] > lmax)
+ if( !(dest[i] > dest[i-1]) && dest[i] > lmax)
break;
i++;
}
}
else {
while(i < GraphTraceLen) {
- if( !(GraphBuffer[i] < GraphBuffer[i-1]) && GraphBuffer[i] < lmin)
+ if( !(dest[i] < dest[i-1]) && dest[i] < lmin)
break;
i++;
}
for (bitidx = 0; i < GraphTraceLen; i++)
{
- if ( (GraphBuffer[i-1] > GraphBuffer[i] && dir == 1 && GraphBuffer[i] > lmax) || (GraphBuffer[i-1] < GraphBuffer[i] && dir == 0 && GraphBuffer[i] < lmin))
+ if ( (dest[i-1] > dest[i] && dir == 1 && dest[i] > lmax) || (dest[i-1] < dest[i] && dir == 0 && dest[i] < lmin))
{
lc = i - lastval;
lastval = i;
block_done = 1;
}
else if(half_switch == 1) {
- BitStream[bitidx++] = 0;
+ bits[bitidx++] = 0;
half_switch = 0;
}
else
half_switch++;
} else if (abs(lc-clock) < tolerance) {
// 64TO
- BitStream[bitidx++] = 1;
+ bits[bitidx++] = 1;
} else {
// Error
warnings++;
if(block_done == 1) {
if(bitidx == 128) {
for(j=0; j<16; j++) {
- Blocks[num_blocks][j] = 128*BitStream[j*8+7]+
- 64*BitStream[j*8+6]+
- 32*BitStream[j*8+5]+
- 16*BitStream[j*8+4]+
- 8*BitStream[j*8+3]+
- 4*BitStream[j*8+2]+
- 2*BitStream[j*8+1]+
- BitStream[j*8];
+ blocks[num_blocks][j] = 128*bits[j*8+7]+
+ 64*bits[j*8+6]+
+ 32*bits[j*8+5]+
+ 16*bits[j*8+4]+
+ 8*bits[j*8+3]+
+ 4*bits[j*8+2]+
+ 2*bits[j*8+1]+
+ bits[j*8];
+
}
num_blocks++;
}
half_switch = 0;
}
if(i < GraphTraceLen)
- {
- if (GraphBuffer[i-1] > GraphBuffer[i]) dir=0;
- else dir = 1;
- }
+ dir =(dest[i-1] > dest[i]) ? 0 : 1;
}
if(bitidx==255)
bitidx=0;
warnings = 0;
if(num_blocks == 4) break;
}
- memcpy(outBlocks, Blocks, 16*num_blocks);
+ memcpy(outBlocks, blocks, 16*num_blocks);
return num_blocks;
}
void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode) {
- uint8_t fwd_bit_count;
uint8_t *dest = BigBuf_get_addr();
- int m=0, i=0;
+ uint16_t bufferlength = BigBuf_max_traceLen();
+ uint32_t i = 0;
+
+ // Clear destination buffer before sending the command 0x80 = average.
+ memset(dest, 0x80, bufferlength);
+
+ uint8_t fwd_bit_count;
//If password mode do login
if (PwdMode == 1) EM4xLogin(Pwd);
fwd_bit_count = Prepare_Cmd( FWD_CMD_READ );
fwd_bit_count += Prepare_Addr( Address );
- m = BigBuf_max_traceLen();
- // Clear destination buffer before sending the command
- memset(dest, 128, m);
// Connect the A/D to the peak-detected low-frequency path.
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
// Now set up the SSC to get the ADC samples that are now streaming at us.
}
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
- i++;
- if (i >= m) break;
+ ++i;
+ if (i >= bufferlength) break;
}
}
+
+ cmd_send(CMD_ACK,0,0,0,0,0);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
LED_D_OFF();
}
//ask raw demod GraphBuffer first
int offset=0, clk=0, invert=0, maxErr=0;
sscanf(Cmd, "%i %i %i %i", &offset, &clk, &invert, &maxErr);
-
- uint8_t BitStream[MAX_DEMOD_BUF_LEN];
+
+ uint8_t BitStream[MAX_DEMOD_BUF_LEN];
size_t size = getFromGraphBuf(BitStream);
- //invert here inverts the ask raw demoded bits which has no effect on the demod, but we need the pointer
int errCnt = askdemod(BitStream, &size, &clk, &invert, maxErr, 0, 0);
if ( errCnt < 0 || errCnt > maxErr ) {
if (g_debugMode) PrintAndLog("DEBUG: no data or error found %d, clock: %d", errCnt, clk);
// NATIONAL CODE, ICAR database
// COUNTRY CODE (ISO3166) or http://cms.abvma.ca/uploads/ManufacturersISOsandCountryCodes.pdf
// FLAG (animal/non-animal)
+/*
+38 IDbits
+10 country code
+1 extra app bit
+14 reserved bits
+1 animal bit
+16 ccitt CRC chksum over 64bit ID CODE.
+24 appli bits.
+
+-- sample: 985121004515220 [ 37FF65B88EF94 ]
+*/
int CmdFDXBdemodBI(const char *Cmd){
int invert = 1;
if (g_debugMode) PrintAndLog("Error BiphaseRawDecode: %d", errCnt);
return 0;
}
-
+
int preambleIndex = FDXBdemodBI(BitStream, &size);
if (preambleIndex < 0){
if (g_debugMode) PrintAndLog("Error FDXBDemod , no startmarker found :: %d",preambleIndex);
return 0;
}
-
+
setDemodBuf(BitStream, 128, preambleIndex);
// remove but don't verify parity. (pType = 2)
}
uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
size_t BitLen = getFromGraphBuf(BitStream);
- if (BitLen==0) return -1;
+ if (BitLen==0) return 0;
uint8_t carrier=countFC(BitStream, BitLen, 0);
if (carrier!=2 && carrier!=4 && carrier!=8){
//invalid carrier
uint8_t * buffer;
uint32_t numbits;
uint32_t position;
-}BitstreamOut;
+} BitstreamOut;
bool _headBit( BitstreamOut *stream)
{
#include "cmdparser.h"
#include "cmdhf14b.h"
#include "cmdmain.h"
+#include "cmdhf14a.h"
static int CmdHelp(const char *Cmd);
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
*/
int CmdSri512Read(const char *Cmd)
{
- UsbCommand c = {CMD_READ_SRI512_TAG, {strtol(Cmd, NULL, 0), 0, 0}};
- SendCommand(&c);
- return 0;
+ UsbCommand c = {CMD_READ_SRI512_TAG, {strtol(Cmd, NULL, 0), 0, 0}};
+ clearCommandBuffer();
+ SendCommand(&c);
+ return 0;
}
/* New command to read the contents of a SRIX4K tag
*/
int CmdSrix4kRead(const char *Cmd)
{
- UsbCommand c = {CMD_READ_SRIX4K_TAG, {strtol(Cmd, NULL, 0), 0, 0}};
- SendCommand(&c);
- return 0;
+ UsbCommand c = {CMD_READ_SRIX4K_TAG, {strtol(Cmd, NULL, 0), 0, 0}};
+ clearCommandBuffer();
+ SendCommand(&c);
+ return 0;
+}
+
+int rawClose(void){
+ UsbCommand resp;
+ UsbCommand c = {CMD_ISO_14443B_COMMAND, {0, 0, 0}};
+ clearCommandBuffer();
+ SendCommand(&c);
+ if (!WaitForResponseTimeout(CMD_ACK,&resp,1000)) {
+ return 0;
+ }
+ return 0;
}
-int CmdHF14BCmdRaw (const char *cmd) {
- UsbCommand resp;
- uint8_t *recv;
- UsbCommand c = {CMD_ISO_14443B_COMMAND, {0, 0, 0}}; // len,recv?
- uint8_t reply=1;
- uint8_t crc=0;
- uint8_t power=0;
+int HF14BCmdRaw(bool reply, bool *crc, bool power, uint8_t *data, uint8_t *datalen, bool verbose){
+ UsbCommand resp;
+ UsbCommand c = {CMD_ISO_14443B_COMMAND, {0, 0, 0}}; // len,recv,power
+ if(*crc)
+ {
+ uint8_t first, second;
+ ComputeCrc14443(CRC_14443_B, data, *datalen, &first, &second);
+ data[*datalen] = first;
+ data[*datalen + 1] = second;
+ *datalen += 2;
+ }
+
+ c.arg[0] = *datalen;
+ c.arg[1] = reply;
+ c.arg[2] = power;
+ memcpy(c.d.asBytes,data,*datalen);
+ clearCommandBuffer();
+ SendCommand(&c);
+
+ if (!reply) return 1;
+
+ if (!WaitForResponseTimeout(CMD_ACK,&resp,1000)) {
+ if (verbose) PrintAndLog("timeout while waiting for reply.");
+ return 0;
+ }
+ *datalen = resp.arg[0];
+ if (verbose) PrintAndLog("received %u octets", *datalen);
+ if(*datalen<2) return 0;
+
+ memcpy(data, resp.d.asBytes, *datalen);
+ if (verbose) PrintAndLog("%s", sprint_hex(data, *datalen));
+
+ uint8_t first, second;
+ ComputeCrc14443(CRC_14443_B, data, *datalen-2, &first, &second);
+ if(data[*datalen-2] == first && data[*datalen-1] == second) {
+ if (verbose) PrintAndLog("CRC OK");
+ *crc = true;
+ } else {
+ if (verbose) PrintAndLog("CRC failed");
+ *crc = false;
+ }
+ return 1;
+}
+
+int CmdHF14BCmdRaw (const char *Cmd) {
+ bool reply = true;
+ bool crc = false;
+ bool power = false;
char buf[5]="";
- int i=0;
uint8_t data[100] = {0x00};
- unsigned int datalen=0, temp;
- char *hexout;
-
- if (strlen(cmd)<3) {
+ uint8_t datalen = 0;
+ unsigned int temp;
+ int i = 0;
+ if (strlen(Cmd)<3) {
PrintAndLog("Usage: hf 14b raw [-r] [-c] [-p] <0A 0B 0C ... hex>");
PrintAndLog(" -r do not read response");
PrintAndLog(" -c calculate and append CRC");
}
// strip
- while (*cmd==' ' || *cmd=='\t') cmd++;
+ while (*Cmd==' ' || *Cmd=='\t') Cmd++;
- while (cmd[i]!='\0') {
- if (cmd[i]==' ' || cmd[i]=='\t') { i++; continue; }
- if (cmd[i]=='-') {
- switch (cmd[i+1]) {
+ while (Cmd[i]!='\0') {
+ if (Cmd[i]==' ' || Cmd[i]=='\t') { i++; continue; }
+ if (Cmd[i]=='-') {
+ switch (Cmd[i+1]) {
case 'r':
case 'R':
- reply=0;
+ reply = false;
break;
case 'c':
case 'C':
- crc=1;
+ crc = true;
break;
case 'p':
case 'P':
- power=1;
+ power = true;
break;
default:
PrintAndLog("Invalid option");
i+=2;
continue;
}
- if ((cmd[i]>='0' && cmd[i]<='9') ||
- (cmd[i]>='a' && cmd[i]<='f') ||
- (cmd[i]>='A' && cmd[i]<='F') ) {
+ if ((Cmd[i]>='0' && Cmd[i]<='9') ||
+ (Cmd[i]>='a' && Cmd[i]<='f') ||
+ (Cmd[i]>='A' && Cmd[i]<='F') ) {
buf[strlen(buf)+1]=0;
- buf[strlen(buf)]=cmd[i];
+ buf[strlen(buf)]=Cmd[i];
i++;
if (strlen(buf)>=2) {
sscanf(buf,"%x",&temp);
- data[datalen]=(uint8_t)(temp & 0xff);
- datalen++;
+ data[datalen++]=(uint8_t)(temp & 0xff);
*buf=0;
}
continue;
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)
{
- CmdsParse(CommandTable, Cmd);
- return 0;
+ CmdsParse(CommandTable, Cmd);
+ return 0;
}
int CmdHelp(const char *Cmd)
{
- CmdsHelp(CommandTable);
- return 0;
+ CmdsHelp(CommandTable);
+ return 0;
}
#include "protocols.h"
#include "data.h"
-#define MAX_UL_BLOCKS 0x0f
-#define MAX_ULC_BLOCKS 0x2b
-#define MAX_ULEV1a_BLOCKS 0x13
-#define MAX_ULEV1b_BLOCKS 0x28
-#define MAX_NTAG_203 0x29
-#define MAX_NTAG_210 0x13
-#define MAX_NTAG_212 0x28
-#define MAX_NTAG_213 0x2c
-#define MAX_NTAG_215 0x86
-#define MAX_NTAG_216 0xe6
+#define MAX_UL_BLOCKS 0x0f
+#define MAX_ULC_BLOCKS 0x2b
+#define MAX_ULEV1a_BLOCKS 0x13
+#define MAX_ULEV1b_BLOCKS 0x28
+#define MAX_NTAG_203 0x29
+#define MAX_NTAG_210 0x13
+#define MAX_NTAG_212 0x28
+#define MAX_NTAG_213 0x2c
+#define MAX_NTAG_215 0x86
+#define MAX_NTAG_216 0xe6
#define MAX_MY_D_NFC 0xff
#define MAX_MY_D_MOVE 0x25
#define MAX_MY_D_MOVE_LEAN 0x0f
memcpy(response, resp.d.asBytes, resplen);
return resplen;
}
-/*
-static int ul_send_cmd_raw_crc( uint8_t *cmd, uint8_t cmdlen, uint8_t *response, uint16_t responseLength, bool append_crc ) {
- UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_RAW | ISO14A_NO_DISCONNECT , cmdlen, 0}};
- if (append_crc)
- c.arg[0] |= ISO14A_APPEND_CRC;
-
- memcpy(c.d.asBytes, cmd, cmdlen);
- clearCommandBuffer();
- SendCommand(&c);
- UsbCommand resp;
- if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) return -1;
- if (!resp.arg[0] && responseLength) return -1;
- uint16_t resplen = (resp.arg[0] < responseLength) ? resp.arg[0] : responseLength;
- memcpy(response, resp.d.asBytes, resplen);
- return resplen;
-}
-*/
static int ul_select( iso14a_card_select_t *card ){
ul_switch_on_field();
// send 300000 + crc (read with extra byte(s))
// UL responds with read of page 0, fudan doesn't respond.
//
- //make sure field is off before calling this function
+ // make sure field is off before calling this function
static int ul_fudan_check( void ){
iso14a_card_select_t card;
if ( !ul_select(&card) )
PrintAndLog(" %02X : NDEF Magic Number", data[0]);
PrintAndLog(" %02X : version %d.%d supported by tag", data[1], (data[1] & 0xF0) >> 4, data[1] & 0x0f);
PrintAndLog(" %02X : Physical Memory Size: %d bytes", data[2], (data[2] + 1) * 8);
- if ( data[2] == 0x12 )
+ if ( data[2] == 0x96 )
+ PrintAndLog(" %02X : NDEF Memory Size: %d bytes", data[2], 48);
+ else if ( data[2] == 0x12 )
PrintAndLog(" %02X : NDEF Memory Size: %d bytes", data[2], 144);
else if ( data[2] == 0x3e )
PrintAndLog(" %02X : NDEF Memory Size: %d bytes", data[2], 496);
//
int CmdHF14AMfUWrBl(const char *Cmd){
- int blockNo = -1;
+ int blockNo = -1;
bool errors = false;
bool hasAuthKey = false;
bool hasPwdKey = false;
uint8_t data[16] = {0x00};
uint8_t authenticationkey[16] = {0x00};
uint8_t *authKeyPtr = authenticationkey;
-
+
while(param_getchar(Cmd, cmdp) != 0x00)
{
switch(param_getchar(Cmd, cmdp))
blockNo = param_get8(Cmd, cmdp+1);
if (blockNo < 0) {
PrintAndLog("Wrong block number");
- errors = true;
+ errors = true;
}
cmdp += 2;
break;
PrintAndLog("block number too large. Max block is %u/0x%02X \n", maxblockno,maxblockno);
return usage_hf_mfu_wrbl();
}
-
+
// Swap endianness
if (swapEndian && hasAuthKey) authKeyPtr = SwapEndian64(authenticationkey, 16, 8);
if (swapEndian && hasPwdKey) authKeyPtr = SwapEndian64(authenticationkey, 4, 4);
- if ( blockNo <= 3)
+ if ( blockNo <= 3)
PrintAndLog("Special Block: %0d (0x%02X) [ %s]", blockNo, blockNo, sprint_hex(blockdata, 4));
else
PrintAndLog("Block: %0d (0x%02X) [ %s]", blockNo, blockNo, sprint_hex(blockdata, 4));
-
+
//Send write Block
UsbCommand c = {CMD_MIFAREU_WRITEBL, {blockNo}};
memcpy(c.d.asBytes,blockdata,4);
- if ( hasAuthKey ) {
+ if ( hasAuthKey ){
c.arg[1] = 1;
memcpy(c.d.asBytes+4,authKeyPtr,16);
}
c.arg[1] = 2;
memcpy(c.d.asBytes+4,authKeyPtr,4);
}
-
+
clearCommandBuffer();
SendCommand(&c);
UsbCommand resp;
} else {
PrintAndLog("Command execute timeout");
}
-
+
return 0;
}
//
blockNo = param_get8(Cmd, cmdp+1);
if (blockNo < 0) {
PrintAndLog("Wrong block number");
- errors = true;
+ errors = true;
}
cmdp += 2;
break;
case 'l':
case 'L':
swapEndian = true;
- cmdp++;
- break;
+ cmdp++;
+ break;
default:
PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = true;
PrintAndLog("block number to large. Max block is %u/0x%02X \n", maxblockno,maxblockno);
return usage_hf_mfu_rdbl();
}
-
+
// Swap endianness
if (swapEndian && hasAuthKey) authKeyPtr = SwapEndian64(authenticationkey, 16, 8);
if (swapEndian && hasPwdKey) authKeyPtr = SwapEndian64(authenticationkey, 4, 4);
-
+
//Read Block
UsbCommand c = {CMD_MIFAREU_READBL, {blockNo}};
if ( hasAuthKey ){
c.arg[1] = 2;
memcpy(c.d.asBytes,authKeyPtr,4);
}
-
+
clearCommandBuffer();
SendCommand(&c);
UsbCommand resp;
int usage_hf_mfu_wrbl(void) {
PrintAndLog("Write a block. It autodetects card type.\n");
PrintAndLog("Usage: hf mfu wrbl b <block number> d <data> k <key> l\n");
- PrintAndLog(" Options:");
+ PrintAndLog(" Options:");
PrintAndLog(" b <no> : block to write");
PrintAndLog(" d <data> : block data - (8 hex symbols)");
PrintAndLog(" k <key> : (optional) key for authentication [UL-C 16bytes, EV1/NTAG 4bytes]");
return 0;
}
+int usage_hf_mfu_eload(void) {
+ PrintAndLog("It loads emulator dump from the file `filename.eml`\n");
+ PrintAndLog("Usage: hf mf eload t <card memory> i <file name w/o `.eml`>\n");
+ PrintAndLog(" Options:");
+ PrintAndLog(" t <card memory> : Tag memorysize/type");
+ PrintAndLog(" i <file> : file name w/o `.eml`");
+ PrintAndLog("");
+ PrintAndLog(" sample : hf mfu eload filename");
+ PrintAndLog(" : hf mfu eload 4 filename");
+ return 0;
+}
+
//
// Mifare Ultralight / Ultralight-C / Ultralight-EV1
// Read and Dump Card Contents, using auto detection of tag size.
}
switch(i){
case 3: tmplockbit = bit[4]; break;
- case 4: tmplockbit = bit[3]; break;
- case 5: tmplockbit = bit[2]; break;
- case 6: tmplockbit = bit[1]; break;
- case 7: tmplockbit = bit[0]; break;
- case 8: tmplockbit = bit[15]; break;
+ case 4: tmplockbit = bit[3]; break;
+ case 5: tmplockbit = bit[2]; break;
+ case 6: tmplockbit = bit[1]; break;
+ case 7: tmplockbit = bit[0]; break;
+ case 8: tmplockbit = bit[15]; break;
case 9: tmplockbit = bit[14]; break;
case 10: tmplockbit = bit[13]; break;
case 11: tmplockbit = bit[12]; break;
//
int CmdHF14AMfucSetPwd(const char *Cmd){
- uint8_t pwd[16] = {0x00};
+ uint8_t pwd[16] = {0x00};
char cmdp = param_getchar(Cmd, 0);
-
+
if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') {
PrintAndLog("Usage: hf mfu setpwd <password (32 hex symbols)>");
PrintAndLog(" [password] - (32 hex symbols)");
PrintAndLog("Command execute timeout");
return 2;
}
-
+
// save old block2.
uint8_t oldblock2[4] = {0x00};
memcpy(resp.d.asBytes, oldblock2, 4);
PrintAndLog("Command execute timeout");
return 3;
}
-
+
// block 1.
c.arg[0] = 1;
c.d.asBytes[0] = uid[3];
}
int CmdHF14AMfuGenDiverseKeys(const char *Cmd){
-
+
uint8_t iv[8] = { 0x00 };
uint8_t block = 0x07;
-
+
// UL-EV1
//04 57 b6 e2 05 3f 80 UID
//4a f8 4b 19 PWD
uint8_t mix[8] = { 0x00 };
uint8_t divkey[8] = { 0x00 };
-
+
memcpy(mix, mifarekeyA, 4);
-
+
mix[4] = mifarekeyA[4] ^ uid[0];
mix[5] = mifarekeyA[5] ^ uid[1];
mix[6] = block ^ uid[2];
mix[7] = uid[3];
-
+
des3_context ctx = { 0x00 };
des3_set2key_enc(&ctx, masterkey);
PrintAndLog("Mifare key :\t %s", sprint_hex(mifarekeyA, sizeof(mifarekeyA)));
PrintAndLog("Message :\t %s", sprint_hex(mix, sizeof(mix)));
PrintAndLog("Diversified key: %s", sprint_hex(divkey+1, 6));
-
+
PrintAndLog("\n DES version");
-
+
for (int i=0; i < sizeof(mifarekeyA); ++i){
dkeyA[i] = (mifarekeyA[i] << 1) & 0xff;
dkeyA[6] |= ((mifarekeyA[i] >> 7) & 1) << (i+1);
memcpy(dmkey+8, dkeyB, 8);
memcpy(dmkey+16, dkeyA, 8);
memset(iv, 0x00, 8);
-
+
des3_set3key_enc(&ctx, dmkey);
des3_crypt_cbc(&ctx // des3_context
// return;
// }
+int CmdHF14AMfuELoad(const char *Cmd)
+{
+ FILE * f;
+ char filename[FILE_PATH_SIZE];
+ char *fnameptr = filename;
+ char buf[64] = {0x00};
+ uint8_t buf8[64] = {0x00};
+ int i, len, blockNum, numBlocks;
+ int nameParamNo = 1;
+
+ char ctmp = param_getchar(Cmd, 0);
+
+ if ( ctmp == 'h' || ctmp == 0x00) {
+ return usage_hf_mfu_eload();
+ }
+/*
+ switch (ctmp) {
+ case '0' : numBlocks = 5*4; break;
+ case '1' :
+ case '\0': numBlocks = 16*4; break;
+ case '2' : numBlocks = 32*4; break;
+ case '4' : numBlocks = 256; break;
+ default: {
+ numBlocks = 16*4;
+ nameParamNo = 0;
+ }
+ }
+
+ len = param_getstr(Cmd,nameParamNo,filename);
+
+ if (len > FILE_PATH_SIZE - 4) len = FILE_PATH_SIZE - 4;
+
+ fnameptr += len;
+
+ sprintf(fnameptr, ".eml");
+
+ // open file
+ f = fopen(filename, "r");
+ if (f == NULL) {
+ PrintAndLog("File %s not found or locked", filename);
+ return 1;
+ }
+
+ blockNum = 0;
+ while(!feof(f)){
+ memset(buf, 0, sizeof(buf));
+
+ if (fgets(buf, sizeof(buf), f) == NULL) {
+
+ if (blockNum >= numBlocks) break;
+
+ PrintAndLog("File reading error.");
+ fclose(f);
+ return 2;
+ }
+
+ if (strlen(buf) < 32){
+ if(strlen(buf) && feof(f))
+ break;
+ PrintAndLog("File content error. Block data must include 32 HEX symbols");
+ fclose(f);
+ return 2;
+ }
+
+ for (i = 0; i < 32; i += 2) {
+ sscanf(&buf[i], "%02x", (unsigned int *)&buf8[i / 2]);
+ }
+
+ if (mfEmlSetMem(buf8, blockNum, 1)) {
+ PrintAndLog("Cant set emul block: %3d", blockNum);
+ fclose(f);
+ return 3;
+ }
+ printf(".");
+ blockNum++;
+
+ if (blockNum >= numBlocks) break;
+ }
+ fclose(f);
+ printf("\n");
+
+ if ((blockNum != numBlocks)) {
+ PrintAndLog("File content error. Got %d must be %d blocks.",blockNum, numBlocks);
+ return 4;
+ }
+ PrintAndLog("Loaded %d blocks from file: %s", blockNum, filename);
+ */
+ return 0;
+}
+
+
//------------------------------------
// Menu Stuff
//------------------------------------
{"dump", CmdHF14AMfUDump, 0, "Dump Ultralight / Ultralight-C / NTAG tag to binary file"},
{"rdbl", CmdHF14AMfURdBl, 0, "Read block"},
{"wrbl", CmdHF14AMfUWrBl, 0, "Write block"},
+ {"eload", CmdHF14AMfuELoad, 0, "Load from file emulator dump"},
{"cauth", CmdHF14AMfucAuth, 0, "Authentication - Ultralight C"},
{"setpwd", CmdHF14AMfucSetPwd, 1, "Set 3des password - Ultralight-C"},
{"setuid", CmdHF14AMfucSetUid, 1, "Set UID - MAGIC tags only"},
// 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
#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
#define CMD_READER_LEGIC_RF 0x0388
#define CMD_WRITER_LEGIC_RF 0x0389
#define CMD_EPA_PACE_COLLECT_NONCE 0x038A
+#define CMD_EPA_PACE_REPLAY 0x038B
#define CMD_SNOOP_ICLASS 0x0392
#define CMD_SIMULATE_TAG_ICLASS 0x0393