Applied PwPiwi's new parity fix.
Applied Marshmellw's fixes for FSKdemod (HID, IO)
FIX: a potential bigbuffer fault given pwpiwi's change inside lfops.c CmdIOdemodFSK & CmdHIDdemodFSK
FIX: change some "int" parameters to uint's.
FIX: changed the lfops.c - DoAcquisition125k_internal to respect pwpiwi's definitions of FREE_BUFFER_OFFSET
HEADS up: The ultralight functions hasn't been verified since pwpiwi's changes.
// is the order in which they go out on the wire.
//=============================================================================
-uint8_t ToSend[512];
+#define TOSEND_BUFFER_SIZE (9*MAX_FRAME_SIZE + 1 + 1 + 2) // 8 data bits and 1 parity bit per payload byte, 1 correction bit, 1 SOC bit, 2 EOC bits
+uint8_t ToSend[TOSEND_BUFFER_SIZE];
int ToSendMax;
static int ToSendBit;
struct common_area common_area __attribute__((section(".commonarea")));
ToSendBit++;
- if(ToSendBit >= sizeof(ToSend)) {
+ if(ToSendMax >= sizeof(ToSend)) {
ToSendBit = 0;
DbpString("ToSendStuffBit overflowed!");
}
cmd_send(CMD_ACK,0,0,0,0,0);
break;
case CMD_HID_DEMOD_FSK:
- CmdHIDdemodFSK(0, 0, 0, 1); // Demodulate HID tag
+ CmdHIDdemodFSK(c->arg[0], 0, 0, 1);
break;
case CMD_HID_SIM_TAG:
- CmdHIDsimTAG(c->arg[0], c->arg[1], 1); // Simulate HID tag by ID
+ CmdHIDsimTAG(c->arg[0], c->arg[1], 1);
break;
- case CMD_HID_CLONE_TAG: // Clone HID tag by ID to T55x7
+ case CMD_HID_CLONE_TAG:
CopyHIDtoT55x7(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes[0]);
break;
case CMD_IO_DEMOD_FSK:
- CmdIOdemodFSK(1, 0, 0, 1); // Demodulate IO tag
+ CmdIOdemodFSK(c->arg[0], 0, 0, 1);
break;
- case CMD_IO_CLONE_TAG: // Clone IO tag by ID to T55x7
+ case CMD_IO_CLONE_TAG:
CopyIOtoT55x7(c->arg[0], c->arg[1], c->d.asBytes[0]);
break;
case CMD_EM410X_WRITE_TAG:
WriteTItag(c->arg[0],c->arg[1],c->arg[2]);
break;
case CMD_SIMULATE_TAG_125K:
- LED_A_ON();
SimulateTagLowFrequency(c->arg[0], c->arg[1], 0);
- FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
- LED_A_OFF();
+ //SimulateTagLowFrequencyA(c->arg[0], c->arg[1]);
break;
case CMD_LF_SIMULATE_BIDIR:
SimulateTagLowFrequencyBidir(c->arg[0], c->arg[1]);
break;
- case CMD_INDALA_CLONE_TAG: // Clone Indala 64-bit tag by UID to T55x7
+ case CMD_INDALA_CLONE_TAG:
CopyIndala64toT55x7(c->arg[0], c->arg[1]);
break;
- case CMD_INDALA_CLONE_TAG_L: // Clone Indala 224-bit tag by UID to T55x7
+ case CMD_INDALA_CLONE_TAG_L:
CopyIndala224toT55x7(c->d.asDwords[0], c->d.asDwords[1], c->d.asDwords[2], c->d.asDwords[3], c->d.asDwords[4], c->d.asDwords[5], c->d.asDwords[6]);
break;
case CMD_T55XX_READ_BLOCK:
case CMD_T55XX_WRITE_BLOCK:
T55xxWriteBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes[0]);
break;
- case CMD_T55XX_READ_TRACE: // Clone HID tag by ID to T55x7
+ case CMD_T55XX_READ_TRACE:
T55xxReadTrace();
break;
- case CMD_PCF7931_READ: // Read PCF7931 tag
+ case CMD_PCF7931_READ:
ReadPCF7931();
cmd_send(CMD_ACK,0,0,0,0,0);
break;
// The large multi-purpose buffer, typically used to hold A/D samples,
// maybe processed in some way.
-//#define BIG_BUFF_SIZE 10000 // PM3 w. 256KB ram
-#define BIG_BUFF_SIZE 10000 // PM3 w. 512KB ram
+#define BIGBUF_SIZE 40000
+uint32_t BigBuf[BIGBUF_SIZE / sizeof(uint32_t)];
+#define TRACE_OFFSET 0
+#define TRACE_SIZE 3000
+#define RECV_CMD_OFFSET (TRACE_OFFSET + TRACE_SIZE)
+#define MAX_FRAME_SIZE 256
+#define MAX_PARITY_SIZE ((MAX_FRAME_SIZE + 1)/ 8)
+#define RECV_CMD_PAR_OFFSET (RECV_CMD_OFFSET + MAX_FRAME_SIZE)
+#define RECV_RESP_OFFSET (RECV_CMD_PAR_OFFSET + MAX_PARITY_SIZE)
+#define RECV_RESP_PAR_OFFSET (RECV_RESP_OFFSET + MAX_FRAME_SIZE)
+#define CARD_MEMORY_OFFSET (RECV_RESP_PAR_OFFSET + MAX_PARITY_SIZE)
+#define CARD_MEMORY_SIZE 4096
+#define DMA_BUFFER_OFFSET CARD_MEMORY_OFFSET
+#define DMA_BUFFER_SIZE CARD_MEMORY_SIZE
+#define FREE_BUFFER_OFFSET (CARD_MEMORY_OFFSET + CARD_MEMORY_SIZE)
+#define FREE_BUFFER_SIZE (BIGBUF_SIZE - FREE_BUFFER_OFFSET - 1)
-uint32_t BigBuf[BIG_BUFF_SIZE];
-// BIG CHANGE - UNDERSTAND THIS BEFORE WE COMMIT
-#define TRACE_OFFSET 0
-#define TRACE_SIZE 4096
-#define RECV_CMD_OFFSET 3032
-#define RECV_CMD_SIZE 64
-#define RECV_RES_OFFSET 3096
-#define RECV_RES_SIZE 64
-#define DMA_BUFFER_OFFSET 3160
-#define DMA_BUFFER_SIZE 4096
-#define FREE_BUFFER_OFFSET 7256
-#define FREE_BUFFER_SIZE 2744
-
-//extern const uint8_t OddByteParity[256];
+extern const uint8_t OddByteParity[256];
extern uint8_t *trace; // = (uint8_t *) BigBuf;
extern int traceLen; // = 0;
extern int rsamples; // = 0;
void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc);
void AcquireTiType(void);
void AcquireRawBitsTI(void);
-void SimulateTagLowFrequency(int period, int gap, int ledcontrol);
-void CmdHIDsimTAG(int hi, int lo, int ledcontrol);
+void SimulateTagLowFrequency( uint16_t period, uint32_t gap, uint8_t ledcontrol);
+void SimulateTagLowFrequencyA(int period, int gap);
+
+void CmdHIDsimTAG(int hi, int lo, uint8_t ledcontrol);
void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol);
void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol);
void CopyIOtoT55x7(uint32_t hi, uint32_t lo, uint8_t longFMT); // Clone an ioProx card to T5557/T5567
void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data);
void ReaderIso14443a(UsbCommand * c);
// Also used in iclass.c
-bool RAMFUNC LogTrace(const uint8_t * btBytes, uint8_t iLen, uint32_t iSamples, uint32_t dwParity, bool readerToTag);
-uint32_t GetParity(const uint8_t * pbtCmd, int iLen);
+bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t len, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag);
+void GetParity(const uint8_t * pbtCmd, uint16_t len, uint8_t *parity);
void iso14a_set_trigger(bool enable);
void iso14a_clear_trace();
void iso14a_set_tracing(bool enable);
void MifareUReadBlock(uint8_t arg0,uint8_t *datain);
void MifareUC_Auth1(uint8_t arg0, uint8_t *datain);
void MifareUC_Auth2(uint32_t arg0, uint8_t *datain);
-void MifareUReadCard(uint8_t arg0,int Pages,uint8_t *datain);
+void MifareUReadCard(uint8_t arg0, int Pages, uint8_t *datain);
void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain);
void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain);
void MifareUWriteBlock(uint8_t arg0,uint8_t *datain);
|| response_apdu[rapdu_length - 4] != 0x90
|| response_apdu[rapdu_length - 3] != 0x00)
{
+ Dbprintf("epa - no select cardaccess");
return -1;
}
|| response_apdu[rapdu_length - 4] != 0x90
|| response_apdu[rapdu_length - 3] != 0x00)
{
+ Dbprintf("epa - no read cardaccess");
return -1;
}
EPA_Finish();
// send the USB packet
- cmd_send(CMD_ACK,step,func_return,0,0,0);
-//UsbSendPacket((void *)ack, sizeof(UsbCommand));
+ cmd_send(CMD_ACK,step,func_return,0,0,0);
}
//-----------------------------------------------------------------------------
*/
// return value of a function
- int func_return;
+ int func_return = 0;
// // initialize ack with 0s
// memset(ack->arg, 0, 12);
// set up communication
func_return = EPA_Setup();
- if (func_return != 0) {
+ if (func_return != 0) {
EPA_PACE_Collect_Nonce_Abort(1, func_return);
+ Dbprintf("epa: setup fucked up! %d", func_return);
return;
}
// increase the timeout (at least some cards really do need this!)
iso14a_set_timeout(0x0002FFFF);
+ Dbprintf("epa: Epic!");
// read the CardAccess file
// this array will hold the CardAccess file
int card_access_length = EPA_Read_CardAccess(card_access, 256);
// the response has to be at least this big to hold the OID
if (card_access_length < 18) {
+ Dbprintf("epa: Too small!");
EPA_PACE_Collect_Nonce_Abort(2, card_access_length);
return;
}
+ Dbprintf("epa: foo!");
+
// this will hold the PACE info of the card
pace_version_info_t pace_version_info;
// search for the PACE OID
return;
}
+ Dbprintf("epa: bar!");
+
// 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);
// save received information
// ack->arg[1] = func_return;
// memcpy(ack->d.asBytes, nonce, func_return);
-// UsbSendPacket((void *)ack, sizeof(UsbCommand));
- cmd_send(CMD_ACK,0,func_return,0,nonce,func_return);
+ cmd_send(CMD_ACK,0,func_return,0,nonce,func_return);
}
//-----------------------------------------------------------------------------
int EPA_Setup()
{
// return code
- int return_code = 0;
+ //int return_code = 0;
+
// card UID
- uint8_t uid[10];
- // card select information
- iso14a_card_select_t card_select_info;
+ //uint8_t uid[10] = {0x00};
+
// power up the field
iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD);
-
+ iso14a_clear_trace();
+ iso14a_set_tracing(TRUE);
+ iso14a_set_timeout(10500);
+
+ // card select information
+ byte_t cardbuf[USB_CMD_DATA_SIZE];
+ memset(cardbuf,0,USB_CMD_DATA_SIZE);
+ iso14a_card_select_t *card = (iso14a_card_select_t*)cardbuf;
+
// select the card
- return_code = iso14443a_select_card(uid, &card_select_info, NULL);
- if (return_code != 1) {
- return 1;
- }
+ // if (!iso14443a_select_card(uid, &card_info, NULL)) {
+ // Dbprintf("Epa: Can't select card");
+ // return -1;
+ // }
+
+ uint8_t wupa[] = { 0x26 }; // 0x26 - REQA 0x52 - WAKE-UP
+ uint8_t sel_all[] = { 0x93,0x20 };
+ uint8_t sel_uid[] = { 0x93,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
+ uint8_t rats[] = { 0xE0,0x81,0x00,0x00 }; // FSD=256, FSDI=8, CID=1
+
+ uint8_t *resp = ((uint8_t *)BigBuf) + RECV_RESP_OFFSET;
+ uint8_t *resp_par = ((uint8_t *)BigBuf) + RECV_RESP_PAR_OFFSET;
+
+ byte_t uid_resp[4];
+ size_t uid_resp_len = 4;
+ uint8_t sak = 0x04; // cascade uid
+ int len;
+
+ // Broadcast for a card, WUPA (0x52) will force response from all cards in the field
+ ReaderTransmitBitsPar(wupa,7,0, NULL);
+
+ // Receive the ATQA
+ if(!ReaderReceive(resp, resp_par)) return -1;
+
+ // SELECT_ALL
+ ReaderTransmit(sel_all,sizeof(sel_all), NULL);
+ if (!ReaderReceive(resp, resp_par)) return -1;
+
+ // uid response from tag
+ memcpy(uid_resp,resp,uid_resp_len);
+
+ // Construct SELECT UID command
+ // transmitting a full UID (1 Byte cmd, 1 Byte NVB, 4 Byte UID, 1 Byte BCC, 2 Bytes CRC)
+ memcpy(sel_uid+2,uid_resp,4); // the UID
+ sel_uid[6] = sel_uid[2] ^ sel_uid[3] ^ sel_uid[4] ^ sel_uid[5]; // calculate and add BCC
+ AppendCrc14443a(sel_uid,7); // calculate and add CRC
+ ReaderTransmit(sel_uid,sizeof(sel_uid), NULL);
+
+ // Receive the SAK
+ if (!ReaderReceive(resp, resp_par)) return -1;
+ sak = resp[0];
+
+ // Request for answer to select
+ AppendCrc14443a(rats, 2);
+ ReaderTransmit(rats, sizeof(rats), NULL);
+
+ if ( !(len = ReaderReceive(resp, resp_par) )) return -1;
+
+ // populate the collected data.
+ memcpy( card->uid, uid_resp, uid_resp_len);
+ card->uidlen += uid_resp_len;
+ card->sak = sak;
+ card->ats_len = len;
+ memcpy(card->ats, resp, sizeof(card->ats));
+
+
// send the PPS request
- ReaderTransmit((uint8_t *)pps, sizeof(pps), NULL);
- uint8_t pps_response[3];
- return_code = ReaderReceive(pps_response);
- if (return_code != 3 || pps_response[0] != 0xD0) {
- return return_code == 0 ? 2 : return_code;
- }
+ // ReaderTransmit((uint8_t *)pps, sizeof(pps), NULL);
+ // uint8_t pps_response[3];
+ // uint8_t pps_response_par[1];
+ // return_code = ReaderReceive(pps_response,pps_response_par);
+ // if (return_code != 3 || pps_response[0] != 0xD0) {
+ // return return_code == 0 ? 2 : return_code;
+ // }
- return 0;
+ return -1;
}
\ No newline at end of file
// Set up eavesdropping mode, frequency divisor which will drive the FPGA
// and analog mux selection.
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
- FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT);
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_TOGGLE_MODE);
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
RELAY_OFF();
// Set up simulator mode, frequency divisor which will drive the FPGA
// and analog mux selection.
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
- FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT);
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD);
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
RELAY_OFF();
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC1);
AT91C_BASE_PIOA->PIO_BSR = GPIO_SSC_FRAME;
- // Disable timer during configuration
+ // Disable timer during configuration
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
- // Capture mode, defaul timer source = MCK/2 (TIMER_CLOCK1), TIOA is external trigger,
+ // Capture mode, default timer source = MCK/2 (TIMER_CLOCK1), TIOA is external trigger,
// external trigger rising edge, load RA on rising edge of TIOA.
AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK | AT91C_TC_ETRGEDG_RISING | AT91C_TC_ABETRG | AT91C_TC_LDRA_RISING;
- // Enable and reset counter
- AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
-
// Reset the received frame, frame count and timing info
memset(rx,0x00,sizeof(rx));
frame_count = 0;
response = 0;
overflow = 0;
+
+ // Enable and reset counter
+ AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
while(!BUTTON_PRESS()) {
// Watchdog hit
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
-// Dbprintf("frame received: %d",frame_count);
-// Dbprintf("Authentication Attempts: %d",(auth_table_len/8));
-// DbpString("All done");
+
+ DbpString("Sim Stopped");
+
}
void ReaderHitag(hitag_function htf, hitag_data* htd) {
int nOutOfCnt;
int OutOfCnt;
int syncBit;
- int parityBits;
int samples;
int highCnt;
int swapper;
int counter;
int bitBuffer;
int dropPosition;
- uint8_t *output;
+ uint8_t *output;
} Uart;
static RAMFUNC int OutOfNDecoding(int bit)
if(Uart.byteCnt == 0) {
// Its not straightforward to show single EOFs
// So just leave it and do not return TRUE
- Uart.output[Uart.byteCnt] = 0xf0;
+ Uart.output[0] = 0xf0;
Uart.byteCnt++;
-
- // Calculate the parity bit for the client...
- Uart.parityBits = 1;
}
else {
return TRUE;
if(Uart.bitCnt == 8) {
Uart.output[Uart.byteCnt] = (Uart.shiftReg & 0xff);
Uart.byteCnt++;
-
- // Calculate the parity bit for the client...
- Uart.parityBits <<= 1;
- //Uart.parityBits ^= OddByteParity[(Uart.shiftReg & 0xff)];
- Uart.parityBits ^= oddparity(Uart.shiftReg & 0xff);
-
Uart.bitCnt = 0;
Uart.shiftReg = 0;
}
Uart.dropPosition--;
Uart.output[Uart.byteCnt] = (Uart.dropPosition & 0xff);
Uart.byteCnt++;
-
- // Calculate the parity bit for the client...
- Uart.parityBits <<= 1;
- //Uart.parityBits ^= OddByteParity[(Uart.dropPosition & 0xff)];
- Uart.parityBits ^= oddparity((Uart.dropPosition & 0xff));
-
Uart.bitCnt = 0;
Uart.shiftReg = 0;
Uart.nOutOfCnt = 0;
Uart.state = STATE_START_OF_COMMUNICATION;
Uart.bitCnt = 0;
Uart.byteCnt = 0;
- Uart.parityBits = 0;
Uart.nOutOfCnt = 0;
Uart.OutOfCnt = 4; // Start at 1/4, could switch to 1/256
Uart.dropPosition = 0;
int bitCount;
int posCount;
int syncBit;
- int parityBits;
uint16_t shiftReg;
int buffer;
int buffer2;
Demod.sub = SUB_FIRST_HALF;
Demod.bitCount = 0;
Demod.shiftReg = 0;
- Demod.parityBits = 0;
Demod.samples = 0;
if(Demod.posCount) {
//if(trigger) LED_A_OFF(); // Not useful in this case...
if(Demod.state == DEMOD_SOF_COMPLETE) {
Demod.output[Demod.len] = 0x0f;
Demod.len++;
- Demod.parityBits <<= 1;
- //Demod.parityBits ^= OddByteParity[0x0f];
- Demod.parityBits ^= oddparity(0x0f);
Demod.state = DEMOD_UNSYNCD;
// error = 0x0f;
return TRUE;
// Tag response does not need to be a complete byte!
if(Demod.len > 0 || Demod.bitCount > 0) {
if(Demod.bitCount > 1) { // was > 0, do not interpret last closing bit, is part of EOF
- Demod.shiftReg >>= (9 - Demod.bitCount);
+ Demod.shiftReg >>= (9 - Demod.bitCount); // rright align data
Demod.output[Demod.len] = Demod.shiftReg & 0xff;
Demod.len++;
- // No parity bit, so just shift a 0
- Demod.parityBits <<= 1;
}
Demod.state = DEMOD_UNSYNCD;
Demod.shiftReg >>= 1;
Demod.output[Demod.len] = (Demod.shiftReg & 0xff);
Demod.len++;
-
- // FOR ISO15639 PARITY NOT SEND OTA, JUST CALCULATE IT FOR THE CLIENT
- Demod.parityBits <<= 1;
- //Demod.parityBits ^= OddByteParity[(Demod.shiftReg & 0xff)];
- Demod.parityBits ^= oddparity((Demod.shiftReg & 0xff));
-
Demod.bitCount = 0;
Demod.shiftReg = 0;
}
// So 32 should be enough!
uint8_t *readerToTagCmd = (((uint8_t *)BigBuf) + RECV_CMD_OFFSET);
// The response (tag -> reader) that we're receiving.
- uint8_t *tagToReaderResponse = (((uint8_t *)BigBuf) + RECV_RES_OFFSET);
+ uint8_t *tagToReaderResponse = (((uint8_t *)BigBuf) + RECV_RESP_OFFSET);
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
//if(!LogTrace(Uart.output,Uart.byteCnt, rsamples, Uart.parityBits,TRUE)) break;
//if(!LogTrace(NULL, 0, Uart.endTime*16 - DELAY_READER_AIR2ARM_AS_SNIFFER, 0, TRUE)) break;
- if(tracing)
- {
- LogTrace(Uart.output,Uart.byteCnt, (GetCountSspClk()-time_0) << 4, Uart.parityBits,TRUE);
- LogTrace(NULL, 0, (GetCountSspClk()-time_0) << 4, 0, TRUE);
+ if(tracing) {
+ uint8_t parity[MAX_PARITY_SIZE];
+ GetParity(Uart.output, Uart.byteCnt, parity);
+ LogTrace(Uart.output,Uart.byteCnt, (GetCountSspClk()-time_0) << 4, (GetCountSspClk()-time_0) << 4, parity, TRUE);
}
rsamples = samples - Demod.samples;
LED_B_ON();
- if(tracing)
- {
- LogTrace(Demod.output,Demod.len, (GetCountSspClk()-time_0) << 4 , Demod.parityBits,FALSE);
- LogTrace(NULL, 0, (GetCountSspClk()-time_0) << 4, 0, FALSE);
+ if(tracing) {
+ uint8_t parity[MAX_PARITY_SIZE];
+ GetParity(Demod.output, Demod.len, parity);
+ LogTrace(Demod.output, Demod.len, (GetCountSspClk()-time_0) << 4, (GetCountSspClk()-time_0) << 4, parity, FALSE);
}
{
uint8_t mac_responses[64] = { 0 };
- Dbprintf("Going into attack mode");
+ Dbprintf("Going into attack mode, %d CSNS sent", numberOfCSNS);
// In this mode, a number of csns are within datain. We'll simulate each one, one at a time
// in order to collect MAC's from the reader. This can later be used in an offlne-attack
// in order to obtain the keys, as in the "dismantling iclass"-paper.
// The usb data is 512 bytes, fitting 65 8-byte CSNs in there.
memcpy(csn_crc, datain+(i*8), 8);
- if(doIClassSimulation(csn_crc,1,mac_responses))
+ if(doIClassSimulation(csn_crc,1,mac_responses+i*8))
{
return; // Button pressed
}
*/
int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived, uint8_t *reader_mac_buf)
{
-
-
// CSN followed by two CRC bytes
uint8_t response2[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
uint8_t response3[] = { 0,0,0,0,0,0,0,0,0,0};
// + 1720..
uint8_t *receivedCmd = (((uint8_t *)BigBuf) + RECV_CMD_OFFSET);
- memset(receivedCmd, 0x44, RECV_CMD_SIZE);
+ memset(receivedCmd, 0x44, MAX_FRAME_SIZE);
int len;
// Prepare card messages
// dbprintf:ing ...
Dbprintf("CSN: %02x %02x %02x %02x %02x %02x %02x %02x",csn[0],csn[1],csn[2],csn[3],csn[4],csn[5],csn[6],csn[7]);
Dbprintf("RDR: (len=%02d): %02x %02x %02x %02x %02x %02x %02x %02x %02x",len,
- receivedCmd[0], receivedCmd[1], receivedCmd[2],
+ receivedCmd[0], receivedCmd[1], receivedCmd[2],
receivedCmd[3], receivedCmd[4], receivedCmd[5],
receivedCmd[6], receivedCmd[7], receivedCmd[8]);
if (reader_mac_buf != NULL)
}
if (tracing) {
- LogTrace(receivedCmd,len, (r2t_time-time_0)<< 4, Uart.parityBits,TRUE);
- LogTrace(NULL,0, (r2t_time-time_0) << 4, 0,TRUE);
+ uint8_t parity[MAX_PARITY_SIZE];
+ GetParity(receivedCmd, len, parity);
+ LogTrace(receivedCmd,len, (r2t_time-time_0)<< 4, (r2t_time-time_0) << 4, parity, TRUE);
if (respdata != NULL) {
- LogTrace(respdata,respsize, (t2r_time-time_0) << 4,SwapBits(GetParity(respdata,respsize),respsize),FALSE);
- LogTrace(NULL,0, (t2r_time-time_0) << 4,0,FALSE);
-
-
+ GetParity(respdata, respsize, parity);
+ LogTrace(respdata, respsize, (t2r_time-time_0) << 4, (t2r_time-time_0) << 4, parity, FALSE);
}
if(!tracing) {
DbpString("Trace full");
}
}
- memset(receivedCmd, 0x44, RECV_CMD_SIZE);
+ memset(receivedCmd, 0x44, MAX_FRAME_SIZE);
}
//Dbprintf("%x", cmdsRecvd);
{
int wait = 0;
int samples = 0;
- int par = 0;
// This is tied to other size changes
CodeIClassCommand(frame,len);
LED_A_ON();
// Store reader command in buffer
- if (tracing) LogTrace(frame,len,rsamples,par,TRUE);
+ if (tracing) {
+ uint8_t par[MAX_PARITY_SIZE];
+ GetParity(frame, len, par);
+ LogTrace(frame, len, rsamples, rsamples, par, TRUE);
+ }
}
//-----------------------------------------------------------------------------
int samples = 0;
if (!GetIClassAnswer(receivedAnswer,160,&samples,0)) return FALSE;
rsamples += samples;
- if (tracing) LogTrace(receivedAnswer,Demod.len,rsamples,Demod.parityBits,FALSE);
+ if (tracing){
+ uint8_t parity[MAX_PARITY_SIZE];
+ GetParity(receivedAnswer, Demod.len, parity);
+ LogTrace(receivedAnswer,Demod.len,rsamples,rsamples,parity,FALSE);
+ }
if(samples == 0) return FALSE;
return Demod.len;
}
uint8_t card_data[24]={0};
uint8_t last_csn[8]={0};
- uint8_t* resp = (((uint8_t *)BigBuf) + 3560); // was 3560 - tied to other size changes
+ uint8_t *resp = (((uint8_t *)BigBuf) + RECV_RESP_OFFSET);
int read_status= 0;
bool abort_after_read = arg0 & FLAG_ICLASS_READER_ONLY_ONCE;
int keyaccess;
} memory;
- uint8_t* resp = (((uint8_t *)BigBuf) + 3560); // was 3560 - tied to other size changes
+ uint8_t* resp = (((uint8_t *)BigBuf) + RECV_RESP_OFFSET);
setupIclassReader();
uint16_t crc = 0;
- uint8_t* resp = (((uint8_t *)BigBuf) + 3560); // was 3560 - tied to other size changes
+ uint8_t* resp = (((uint8_t *)BigBuf) + RECV_RESP_OFFSET);
// Reset trace buffer
memset(trace, 0x44, RECV_CMD_OFFSET);
// Modulate BPSK
// Signal field is off with the appropriate LED
LED_D_OFF();
- FpgaWriteConfWord(
- FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_MODULATE_BPSK);
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_MODULATE_BPSK);
AT91C_BASE_SSC->SSC_THR = 0xff;
FpgaSetupSsc();
//variables used for timing purposes:
//these are in ssp_clk cycles:
-uint32_t NextTransferTime;
-uint32_t LastTimeProxToAirStart;
-uint32_t LastProxToAirDuration;
+static uint32_t NextTransferTime;
+static uint32_t LastTimeProxToAirStart;
+static uint32_t LastProxToAirDuration;
#define SEC_Y 0x00
#define SEC_Z 0xc0
-//replaced large parity table with small parity generation function - saves flash code
-/*
const uint8_t OddByteParity[256] = {
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1
};
-*/
void iso14a_set_trigger(bool enable) {
trigger = enable;
// Generate the parity value for a byte sequence
//
//-----------------------------------------------------------------------------
-/*
byte_t oddparity (const byte_t bt)
{
return OddByteParity[bt];
}
-*/
-uint32_t GetParity(const uint8_t * pbtCmd, int iLen)
+void GetParity(const uint8_t * pbtCmd, uint16_t iLen, uint8_t *par)
{
- int i;
- uint32_t dwPar = 0;
-
- // Generate the parity bits
- for (i = 0; i < iLen; i++) {
- // and save them to a 32Bit word
- //dwPar |= ((OddByteParity[pbtCmd[i]]) << i);
- dwPar |= (oddparity(pbtCmd[i]) << i);
+ uint16_t paritybit_cnt = 0;
+ uint16_t paritybyte_cnt = 0;
+ uint8_t parityBits = 0;
+
+ for (uint16_t i = 0; i < iLen; i++) {
+ // Generate the parity bits
+ parityBits |= ((OddByteParity[pbtCmd[i]]) << (7-paritybit_cnt));
+ if (paritybit_cnt == 7) {
+ par[paritybyte_cnt] = parityBits; // save 8 Bits parity
+ parityBits = 0; // and advance to next Parity Byte
+ paritybyte_cnt++;
+ paritybit_cnt = 0;
+ } else {
+ paritybit_cnt++;
+ }
}
- return dwPar;
+
+ // save remaining parity bits
+ par[paritybyte_cnt] = parityBits;
+
}
void AppendCrc14443a(uint8_t* data, int len)
}
// The function LogTrace() is also used by the iClass implementation in iClass.c
-bool RAMFUNC LogTrace(const uint8_t * btBytes, uint8_t iLen, uint32_t timestamp, uint32_t dwParity, bool readerToTag)
+bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag)
{
if (!tracing) return FALSE;
+
+ uint16_t num_paritybytes = (iLen-1)/8 + 1; // number of valid paritybytes in *parity
+ uint16_t duration = timestamp_end - timestamp_start;
+
// Return when trace is full
- if (traceLen + sizeof(timestamp) + sizeof(dwParity) + iLen >= TRACE_SIZE) {
+ if (traceLen + sizeof(iLen) + sizeof(timestamp_start) + sizeof(duration) + num_paritybytes + iLen >= TRACE_SIZE) {
tracing = FALSE; // don't trace any more
return FALSE;
}
- // Trace the random, i'm curious
- trace[traceLen++] = ((timestamp >> 0) & 0xff);
- trace[traceLen++] = ((timestamp >> 8) & 0xff);
- trace[traceLen++] = ((timestamp >> 16) & 0xff);
- trace[traceLen++] = ((timestamp >> 24) & 0xff);
-
+ // Traceformat:
+ // 32 bits timestamp (little endian)
+ // 16 bits duration (little endian)
+ // 16 bits data length (little endian, Highest Bit used as readerToTag flag)
+ // y Bytes data
+ // x Bytes parity (one byte per 8 bytes data)
+
+ // timestamp (start)
+ trace[traceLen++] = ((timestamp_start >> 0) & 0xff);
+ trace[traceLen++] = ((timestamp_start >> 8) & 0xff);
+ trace[traceLen++] = ((timestamp_start >> 16) & 0xff);
+ trace[traceLen++] = ((timestamp_start >> 24) & 0xff);
+
+ // duration
+ trace[traceLen++] = ((duration >> 0) & 0xff);
+ trace[traceLen++] = ((duration >> 8) & 0xff);
+
+ // data length
+ trace[traceLen++] = ((iLen >> 0) & 0xff);
+ trace[traceLen++] = ((iLen >> 8) & 0xff);
+
+ // readerToTag flag
if (!readerToTag) {
trace[traceLen - 1] |= 0x80;
- }
- trace[traceLen++] = ((dwParity >> 0) & 0xff);
- trace[traceLen++] = ((dwParity >> 8) & 0xff);
- trace[traceLen++] = ((dwParity >> 16) & 0xff);
- trace[traceLen++] = ((dwParity >> 24) & 0xff);
- trace[traceLen++] = iLen;
+ }
+
+ // data bytes
if (btBytes != NULL && iLen != 0) {
memcpy(trace + traceLen, btBytes, iLen);
}
- traceLen += iLen;
+ traceLen += iLen;
+
+ // parity bytes
+ if (parity != NULL && iLen != 0) {
+ memcpy(trace + traceLen, parity, num_paritybytes);
+ }
+ traceLen += num_paritybytes;
+
return TRUE;
}
Uart.state = STATE_UNSYNCD;
Uart.bitCount = 0;
Uart.len = 0; // number of decoded data bytes
+ Uart.parityLen = 0; // number of decoded parity bytes
Uart.shiftReg = 0; // shiftreg to hold decoded data bits
- Uart.parityBits = 0; //
+ Uart.parityBits = 0; // holds 8 parity bits
Uart.twoBits = 0x0000; // buffer for 2 Bits
Uart.highCnt = 0;
Uart.startTime = 0;
Uart.endTime = 0;
}
+void UartInit(uint8_t *data, uint8_t *parity)
+{
+ Uart.output = data;
+ Uart.parity = parity;
+ UartReset();
+}
// use parameter non_real_time to provide a timestamp. Set to 0 if the decoder should measure real time
static RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time)
Uart.twoBits = (Uart.twoBits << 8) | bit;
- if (Uart.state == STATE_UNSYNCD) { // not yet synced
+ if (Uart.state == STATE_UNSYNCD) { // not yet synced
+
if (Uart.highCnt < 7) { // wait for a stable unmodulated signal
- if (Uart.twoBits == 0xffff) {
+ if (Uart.twoBits == 0xffff)
Uart.highCnt++;
- } else {
+ else
Uart.highCnt = 0;
- }
- } else {
+ } else {
Uart.syncBit = 0xFFFF; // not set
// look for 00xx1111 (the start bit)
if ((Uart.twoBits & 0x6780) == 0x0780) Uart.syncBit = 7;
Uart.parityBits |= ((Uart.shiftReg >> 8) & 0x01); // store parity bit
Uart.bitCount = 0;
Uart.shiftReg = 0;
+ if((Uart.len & 0x0007) == 0) { // every 8 data bytes
+ Uart.parity[Uart.parityLen++] = Uart.parityBits; // store 8 parity bits
+ Uart.parityBits = 0;
+ }
}
}
}
Uart.parityBits |= ((Uart.shiftReg >> 8) & 0x01); // store parity bit
Uart.bitCount = 0;
Uart.shiftReg = 0;
+ if ((Uart.len & 0x0007) == 0) { // every 8 data bytes
+ Uart.parity[Uart.parityLen++] = Uart.parityBits; // store 8 parity bits
+ Uart.parityBits = 0;
+ }
}
} else { // no modulation in both halves - Sequence Y
if (Uart.state == STATE_MILLER_Z || Uart.state == STATE_MILLER_Y) { // Y after logic "0" - End of Communication
Uart.state = STATE_UNSYNCD;
- if(Uart.len == 0 && Uart.bitCount > 0) { // if we decoded some bits
- Uart.shiftReg >>= (9 - Uart.bitCount); // add them to the output
- Uart.output[Uart.len++] = (Uart.shiftReg & 0xff);
- Uart.parityBits <<= 1; // no parity bit - add "0"
- Uart.bitCount--; // last "0" was part of the EOC sequence
- }
+ Uart.bitCount--; // last "0" was part of EOC sequence
+ Uart.shiftReg <<= 1; // drop it
+ if(Uart.bitCount > 0) { // if we decoded some bits
+ Uart.shiftReg >>= (9 - Uart.bitCount); // right align them
+ Uart.output[Uart.len++] = (Uart.shiftReg & 0xff); // add last byte to the output
+ Uart.parityBits <<= 1; // add a (void) parity bit
+ Uart.parityBits <<= (8 - (Uart.len & 0x0007)); // left align parity bits
+ Uart.parity[Uart.parityLen++] = Uart.parityBits; // and store it
return TRUE;
+ } else if (Uart.len & 0x0007) { // there are some parity bits to store
+ Uart.parityBits <<= (8 - (Uart.len & 0x0007)); // left align remaining parity bits
+ Uart.parity[Uart.parityLen++] = Uart.parityBits; // and store them
+ return TRUE; // we are finished with decoding the raw data sequence
+ }
}
if (Uart.state == STATE_START_OF_COMMUNICATION) { // error - must not follow directly after SOC
UartReset();
Uart.parityBits |= ((Uart.shiftReg >> 8) & 0x01); // store parity bit
Uart.bitCount = 0;
Uart.shiftReg = 0;
+ if ((Uart.len & 0x0007) == 0) { // every 8 data bytes
+ Uart.parity[Uart.parityLen++] = Uart.parityBits; // store 8 parity bits
+ Uart.parityBits = 0;
+ }
}
}
}
}
- }
+ }
return FALSE; // not finished yet, need more data
}
{
Demod.state = DEMOD_UNSYNCD;
Demod.len = 0; // number of decoded data bytes
+ Demod.parityLen = 0;
Demod.shiftReg = 0; // shiftreg to hold decoded data bits
Demod.parityBits = 0; //
Demod.collisionPos = 0; // Position of collision bit
Demod.endTime = 0;
}
+void DemodInit(uint8_t *data, uint8_t *parity)
+{
+ Demod.output = data;
+ Demod.parity = parity;
+ DemodReset();
+}
+
// use parameter non_real_time to provide a timestamp. Set to 0 if the decoder should measure real time
static RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non_real_time)
{
Demod.parityBits |= ((Demod.shiftReg >> 8) & 0x01); // store parity bit
Demod.bitCount = 0;
Demod.shiftReg = 0;
+ if((Demod.len & 0x0007) == 0) { // every 8 data bytes
+ Demod.parity[Demod.parityLen++] = Demod.parityBits; // store 8 parity bits
+ Demod.parityBits = 0;
+ }
}
Demod.endTime = Demod.startTime + 8*(9*Demod.len + Demod.bitCount + 1) - 4;
} else { // no modulation in first half
Demod.parityBits |= ((Demod.shiftReg >> 8) & 0x01); // store parity bit
Demod.bitCount = 0;
Demod.shiftReg = 0;
+ if ((Demod.len & 0x0007) == 0) { // every 8 data bytes
+ Demod.parity[Demod.parityLen++] = Demod.parityBits; // store 8 parity bits1
+ Demod.parityBits = 0;
+ }
}
Demod.endTime = Demod.startTime + 8*(9*Demod.len + Demod.bitCount + 1);
} else { // no modulation in both halves - End of communication
- if (Demod.len > 0 || Demod.bitCount > 0) { // received something
- if(Demod.bitCount > 0) { // if we decoded bits
- Demod.shiftReg >>= (9 - Demod.bitCount); // add the remaining decoded bits to the output
- Demod.output[Demod.len++] = Demod.shiftReg & 0xff;
- // No parity bit, so just shift a 0
- Demod.parityBits <<= 1;
- }
- return TRUE; // we are finished with decoding the raw data sequence
+ if(Demod.bitCount > 0) { // there are some remaining data bits
+ Demod.shiftReg >>= (9 - Demod.bitCount); // right align the decoded bits
+ Demod.output[Demod.len++] = Demod.shiftReg & 0xff; // and add them to the output
+ Demod.parityBits <<= 1; // add a (void) parity bit
+ Demod.parityBits <<= (8 - (Demod.len & 0x0007)); // left align remaining parity bits
+ Demod.parity[Demod.parityLen++] = Demod.parityBits; // and store them
+ return TRUE;
+ } else if (Demod.len & 0x0007) { // there are some parity bits to store
+ Demod.parityBits <<= (8 - (Demod.len & 0x0007)); // left align remaining parity bits
+ Demod.parity[Demod.parityLen++] = Demod.parityBits; // and store them
+ return TRUE; // we are finished with decoding the raw data sequence
} else { // nothing received. Start over
DemodReset();
}
// The command (reader -> tag) that we're receiving.
// The length of a received command will in most cases be no more than 18 bytes.
// So 32 should be enough!
- uint8_t *receivedCmd = (((uint8_t *)BigBuf) + RECV_CMD_OFFSET);
+ uint8_t *receivedCmd = ((uint8_t *)BigBuf) + RECV_CMD_OFFSET;
+ uint8_t *receivedCmdPar = ((uint8_t *)BigBuf) + RECV_CMD_PAR_OFFSET;
+
// The response (tag -> reader) that we're receiving.
- uint8_t *receivedResponse = (((uint8_t *)BigBuf) + RECV_RES_OFFSET);
-
+ uint8_t *receivedResponse = ((uint8_t *)BigBuf) + RECV_RESP_OFFSET;
+ uint8_t *receivedResponsePar = ((uint8_t *)BigBuf) + RECV_RESP_PAR_OFFSET;
+
// As we receive stuff, we copy it from receivedCmd or receivedResponse
// into trace, along with its length and other annotations.
//uint8_t *trace = (uint8_t *)BigBuf;
iso14443a_setup(FPGA_HF_ISO14443A_SNIFFER);
// Set up the demodulator for tag -> reader responses.
- Demod.output = receivedResponse;
+ DemodInit(receivedResponse, receivedResponsePar);
// Set up the demodulator for the reader -> tag commands
- Uart.output = receivedCmd;
+ UartInit(receivedCmd, receivedCmdPar);
// Setup and start DMA.
FpgaSetupSscDma((uint8_t *)dmaBuf, DMA_BUFFER_SIZE);
if ((!triggered) && (param & 0x02) && (Uart.len == 1) && (Uart.bitCount == 7)) triggered = TRUE;
if(triggered) {
- if (!LogTrace(receivedCmd, Uart.len, Uart.startTime*16 - DELAY_READER_AIR2ARM_AS_SNIFFER, Uart.parityBits, TRUE)) break;
- if (!LogTrace(NULL, 0, Uart.endTime*16 - DELAY_READER_AIR2ARM_AS_SNIFFER, 0, TRUE)) break;
+ if (!LogTrace(receivedCmd,
+ Uart.len,
+ Uart.startTime*16 - DELAY_READER_AIR2ARM_AS_SNIFFER,
+ Uart.endTime*16 - DELAY_READER_AIR2ARM_AS_SNIFFER,
+ Uart.parity,
+ TRUE)) break;
}
/* And ready to receive another command. */
UartReset();
if(ManchesterDecoding(tagdata, 0, (rsamples-1)*4)) {
LED_B_ON();
- if (!LogTrace(receivedResponse, Demod.len, Demod.startTime*16 - DELAY_TAG_AIR2ARM_AS_SNIFFER, Demod.parityBits, FALSE)) break;
- if (!LogTrace(NULL, 0, Demod.endTime*16 - DELAY_TAG_AIR2ARM_AS_SNIFFER, 0, FALSE)) break;
+ if (!LogTrace(receivedResponse,
+ Demod.len,
+ Demod.startTime*16 - DELAY_TAG_AIR2ARM_AS_SNIFFER,
+ Demod.endTime*16 - DELAY_TAG_AIR2ARM_AS_SNIFFER,
+ Demod.parity,
+ FALSE)) break;
if ((!triggered) && (param & 0x01)) triggered = TRUE;
//-----------------------------------------------------------------------------
// Prepare tag messages
//-----------------------------------------------------------------------------
-static void CodeIso14443aAsTagPar(const uint8_t *cmd, int len, uint32_t dwParity)
+static void CodeIso14443aAsTagPar(const uint8_t *cmd, uint16_t len, uint8_t *parity)
{
- int i;
-
ToSendReset();
// Correction bit, might be removed when not needed
ToSend[++ToSendMax] = SEC_D;
LastProxToAirDuration = 8 * ToSendMax - 4;
- for(i = 0; i < len; i++) {
- int j;
+ for( uint16_t i = 0; i < len; i++) {
uint8_t b = cmd[i];
// Data bits
- for(j = 0; j < 8; j++) {
+ for(uint16_t j = 0; j < 8; j++) {
if(b & 1) {
ToSend[++ToSendMax] = SEC_D;
} else {
}
// Get the parity bit
- //if ((dwParity >> i) & 0x01) {
- if (oddparity(cmd[i]) & 0x01) {
+ if (parity[i>>3] & (0x80>>(i&0x0007))) {
ToSend[++ToSendMax] = SEC_D;
LastProxToAirDuration = 8 * ToSendMax - 4;
} else {
ToSendMax++;
}
-static void CodeIso14443aAsTag(const uint8_t *cmd, int len){
- CodeIso14443aAsTagPar(cmd, len, GetParity(cmd, len));
+static void CodeIso14443aAsTag(const uint8_t *cmd, uint16_t len)
+{
+ uint8_t par[MAX_PARITY_SIZE];
+
+ GetParity(cmd, len, par);
+ CodeIso14443aAsTagPar(cmd, len, par);
}
// Stop when button is pressed
// Or return TRUE when command is captured
//-----------------------------------------------------------------------------
-static int GetIso14443aCommandFromReader(uint8_t *received, int *len, int maxLen)
+static int GetIso14443aCommandFromReader(uint8_t *received, uint8_t *parity, int *len)
{
// Set FPGA mode to "simulated ISO 14443 tag", no modulation (listen
// only, since we are receiving, not transmitting).
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_LISTEN);
// Now run a `software UART' on the stream of incoming samples.
- UartReset();
- Uart.output = received;
+ UartInit(received, parity);
// clear RXRDY:
uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
}
}
-static int EmSendCmd14443aRaw(uint8_t *resp, int respLen, bool correctionNeeded);
+static int EmSendCmd14443aRaw(uint8_t *resp, uint16_t respLen, bool correctionNeeded);
int EmSend4bitEx(uint8_t resp, bool correctionNeeded);
int EmSend4bit(uint8_t resp);
-int EmSendCmdExPar(uint8_t *resp, int respLen, bool correctionNeeded, uint32_t par);
-int EmSendCmdExPar(uint8_t *resp, int respLen, bool correctionNeeded, uint32_t par);
-int EmSendCmdEx(uint8_t *resp, int respLen, bool correctionNeeded);
-int EmSendCmd(uint8_t *resp, int respLen);
-int EmSendCmdPar(uint8_t *resp, int respLen, uint32_t par);
-bool EmLogTrace(uint8_t *reader_data, uint16_t reader_len, uint32_t reader_StartTime, uint32_t reader_EndTime, uint32_t reader_Parity,
- uint8_t *tag_data, uint16_t tag_len, uint32_t tag_StartTime, uint32_t tag_EndTime, uint32_t tag_Parity);
+int EmSendCmdExPar(uint8_t *resp, uint16_t respLen, bool correctionNeeded, uint8_t *par);
+int EmSendCmdEx(uint8_t *resp, uint16_t respLen, bool correctionNeeded);
+int EmSendCmd(uint8_t *resp, uint16_t respLen);
+int EmSendCmdPar(uint8_t *resp, uint16_t respLen, uint8_t *par);
+bool EmLogTrace(uint8_t *reader_data, uint16_t reader_len, uint32_t reader_StartTime, uint32_t reader_EndTime, uint8_t *reader_Parity,
+ uint8_t *tag_data, uint16_t tag_len, uint32_t tag_StartTime, uint32_t tag_EndTime, uint8_t *tag_Parity);
static uint8_t* free_buffer_pointer = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET);
response_info->modulation = free_buffer_pointer;
// Determine the maximum size we can use from our buffer
- size_t max_buffer_size = (((uint8_t *)BigBuf)+FREE_BUFFER_OFFSET+FREE_BUFFER_SIZE)-free_buffer_pointer;
+ size_t max_buffer_size = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET + FREE_BUFFER_SIZE) - free_buffer_pointer;
// Forward the prepare tag modulation function to the inner function
if (prepare_tag_modulation(response_info,max_buffer_size)) {
ComputeCrc14443(CRC_14443_A, response3a, 1, &response3a[1], &response3a[2]);
uint8_t response5[] = { 0x00, 0x00, 0x00, 0x00 }; // Very random tag nonce
- uint8_t response6[] = { 0x04, 0x58, 0x00, 0x02, 0x00, 0x00 }; // dummy ATS (pseudo-ATR), answer to RATS
+ uint8_t response6[] = { 0x04, 0x58, 0x80, 0x02, 0x00, 0x00 }; // dummy ATS (pseudo-ATR), answer to RATS:
+ // Format byte = 0x58: FSCI=0x08 (FSC=256), TA(1) and TC(1) present,
+ // TA(1) = 0x80: different divisors not supported, DR = 1, DS = 1
+ // TB(1) = not present. Defaults: FWI = 4 (FWT = 256 * 16 * 2^4 * 1/fc = 4833us), SFGI = 0 (SFG = 256 * 16 * 2^0 * 1/fc = 302us)
+ // TC(1) = 0x02: CID supported, NAD not supported
ComputeCrc14443(CRC_14443_A, response6, 4, &response6[4], &response6[5]);
#define TAG_RESPONSE_COUNT 7
prepare_allocated_tag_modulation(&responses[i]);
}
- uint8_t *receivedCmd = (((uint8_t *)BigBuf) + RECV_CMD_OFFSET);
int len = 0;
// To control where we are in the protocol
// We need to listen to the high-frequency, peak-detected path.
iso14443a_setup(FPGA_HF_ISO14443A_TAGSIM_LISTEN);
+ // buffers used on software Uart:
+ uint8_t *receivedCmd = ((uint8_t *)BigBuf) + RECV_CMD_OFFSET;
+ uint8_t *receivedCmdPar = ((uint8_t *)BigBuf) + RECV_CMD_PAR_OFFSET;
+
cmdsRecvd = 0;
tag_response_info_t* p_response;
for(;;) {
// Clean receive command buffer
- if(!GetIso14443aCommandFromReader(receivedCmd, &len, RECV_CMD_SIZE)) {
+ if(!GetIso14443aCommandFromReader(receivedCmd, receivedCmdPar, &len)) {
DbpString("Button press");
- break;
+ break;
}
p_response = NULL;
- // doob - added loads of debug strings so we can see what the reader is saying to us during the sim as hi14alist is not populated
// Okay, look at the command now.
lastorder = order;
if(receivedCmd[0] == 0x26) { // Received a REQUEST
p_response = &responses[0]; order = 6;
} else if(receivedCmd[1] == 0x20 && receivedCmd[0] == 0x93) { // Received request for UID (cascade 1)
p_response = &responses[1]; order = 2;
- } else if(receivedCmd[1] == 0x20 && receivedCmd[0] == 0x95) { // Received request for UID (cascade 2)
+ } else if(receivedCmd[1] == 0x20 && receivedCmd[0] == 0x95) { // Received request for UID (cascade 2)
p_response = &responses[2]; order = 20;
} else if(receivedCmd[1] == 0x70 && receivedCmd[0] == 0x93) { // Received a SELECT (cascade 1)
p_response = &responses[3]; order = 3;
} else if(receivedCmd[1] == 0x70 && receivedCmd[0] == 0x95) { // Received a SELECT (cascade 2)
p_response = &responses[4]; order = 30;
} else if(receivedCmd[0] == 0x30) { // Received a (plain) READ
- EmSendCmdEx(data+(4*receivedCmd[0]),16,false);
+ EmSendCmdEx(data+(4*receivedCmd[1]),16,false);
// Dbprintf("Read request from reader: %x %x",receivedCmd[0],receivedCmd[1]);
// We already responded, do not send anything with the EmSendCmd14443aRaw() that is called below
p_response = NULL;
} else if(receivedCmd[0] == 0x50) { // Received a HALT
-// DbpString("Reader requested we HALT!:");
+
if (tracing) {
- LogTrace(receivedCmd, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parityBits, TRUE);
- LogTrace(NULL, 0, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, 0, TRUE);
+ LogTrace(receivedCmd, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
}
p_response = NULL;
} else if(receivedCmd[0] == 0x60 || receivedCmd[0] == 0x61) { // Received an authentication request
} else {
p_response = &responses[6]; order = 70;
}
- } else if (order == 7 && len == 8) { // Received authentication request
+ } else if (order == 7 && len == 8) { // Received {nr] and {ar} (part of authentication)
if (tracing) {
- LogTrace(receivedCmd, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parityBits, TRUE);
- LogTrace(NULL, 0, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, 0, TRUE);
+ LogTrace(receivedCmd, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
}
uint32_t nr = bytes_to_num(receivedCmd,4);
uint32_t ar = bytes_to_num(receivedCmd+4,4);
default: {
// Never seen this command before
if (tracing) {
- LogTrace(receivedCmd, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parityBits, TRUE);
- LogTrace(NULL, 0, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, 0, TRUE);
+ LogTrace(receivedCmd, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
}
Dbprintf("Received unknown command (len=%d):",len);
Dbhexdump(len,receivedCmd,false);
if (prepare_tag_modulation(&dynamic_response_info,DYNAMIC_MODULATION_BUFFER_SIZE) == false) {
Dbprintf("Error preparing tag response");
if (tracing) {
- LogTrace(receivedCmd, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parityBits, TRUE);
- LogTrace(NULL, 0, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, 0, TRUE);
+ LogTrace(receivedCmd, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
}
break;
}
if (p_response != NULL) {
EmSendCmd14443aRaw(p_response->modulation, p_response->modulation_n, receivedCmd[0] == 0x52);
// do the tracing for the previous reader request and this tag answer:
+ uint8_t par[MAX_PARITY_SIZE];
+ GetParity(p_response->response, p_response->response_n, par);
+
EmLogTrace(Uart.output,
Uart.len,
Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG,
Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG,
- Uart.parityBits,
+ Uart.parity,
p_response->response,
p_response->response_n,
LastTimeProxToAirStart*16 + DELAY_ARM2AIR_AS_TAG,
(LastTimeProxToAirStart + p_response->ProxToAirDuration)*16 + DELAY_ARM2AIR_AS_TAG,
- SwapBits(GetParity(p_response->response, p_response->response_n), p_response->response_n));
+ par);
}
if (!tracing) {
// if == 0: transfer immediately and return time of transfer
// if != 0: delay transfer until time specified
//-------------------------------------------------------------------------------------
-static void TransmitFor14443a(const uint8_t *cmd, int len, uint32_t *timing)
+static void TransmitFor14443a(const uint8_t *cmd, uint16_t len, uint32_t *timing)
{
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);
//-----------------------------------------------------------------------------
// Prepare reader command (in bits, support short frames) to send to FPGA
//-----------------------------------------------------------------------------
-void CodeIso14443aBitsAsReaderPar(const uint8_t * cmd, int bits, uint32_t dwParity)
+void CodeIso14443aBitsAsReaderPar(const uint8_t * cmd, uint16_t bits, const uint8_t *parity)
{
int i, j;
int last;
b >>= 1;
}
- // Only transmit (last) parity bit if we transmitted a complete byte
+ // Only transmit parity bit if we transmitted a complete byte
if (j == 8) {
// Get the parity bit
- if ((dwParity >> i) & 0x01) {
+ if (parity[i>>3] & (0x80 >> (i&0x0007))) {
// Sequence X
ToSend[++ToSendMax] = SEC_X;
LastProxToAirDuration = 8 * (ToSendMax+1) - 2;
//-----------------------------------------------------------------------------
// Prepare reader command to send to FPGA
//-----------------------------------------------------------------------------
-void CodeIso14443aAsReaderPar(const uint8_t * cmd, int len, uint32_t dwParity)
+void CodeIso14443aAsReaderPar(const uint8_t * cmd, uint16_t len, const uint8_t *parity)
{
- CodeIso14443aBitsAsReaderPar(cmd,len*8,dwParity);
+ CodeIso14443aBitsAsReaderPar(cmd, len*8, parity);
}
//-----------------------------------------------------------------------------
// Stop when button is pressed (return 1) or field was gone (return 2)
// Or return 0 when command is captured
//-----------------------------------------------------------------------------
-static int EmGetCmd(uint8_t *received, int *len)
+static int EmGetCmd(uint8_t *received, uint16_t *len, uint8_t *parity)
{
*len = 0;
AT91C_BASE_ADC->ADC_CR = AT91C_ADC_START;
// Now run a 'software UART' on the stream of incoming samples.
- UartReset();
- Uart.output = received;
+ UartInit(received, parity);
// Clear RXRDY:
uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
}
-static int EmSendCmd14443aRaw(uint8_t *resp, int respLen, bool correctionNeeded)
+static int EmSendCmd14443aRaw(uint8_t *resp, uint16_t respLen, bool correctionNeeded)
{
uint8_t b;
uint16_t i = 0;
Code4bitAnswerAsTag(resp);
int res = EmSendCmd14443aRaw(ToSend, ToSendMax, correctionNeeded);
// do the tracing for the previous reader request and this tag answer:
+ uint8_t par[1];
+ GetParity(&resp, 1, par);
EmLogTrace(Uart.output,
Uart.len,
Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG,
Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG,
- Uart.parityBits,
+ Uart.parity,
&resp,
1,
LastTimeProxToAirStart*16 + DELAY_ARM2AIR_AS_TAG,
(LastTimeProxToAirStart + LastProxToAirDuration)*16 + DELAY_ARM2AIR_AS_TAG,
- SwapBits(GetParity(&resp, 1), 1));
+ par);
return res;
}
return EmSend4bitEx(resp, false);
}
-int EmSendCmdExPar(uint8_t *resp, int respLen, bool correctionNeeded, uint32_t par){
+int EmSendCmdExPar(uint8_t *resp, uint16_t respLen, bool correctionNeeded, uint8_t *par){
CodeIso14443aAsTagPar(resp, respLen, par);
int res = EmSendCmd14443aRaw(ToSend, ToSendMax, correctionNeeded);
// do the tracing for the previous reader request and this tag answer:
Uart.len,
Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG,
Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG,
- Uart.parityBits,
+ Uart.parity,
resp,
respLen,
LastTimeProxToAirStart*16 + DELAY_ARM2AIR_AS_TAG,
(LastTimeProxToAirStart + LastProxToAirDuration)*16 + DELAY_ARM2AIR_AS_TAG,
- SwapBits(GetParity(resp, respLen), respLen));
+ par);
return res;
}
-int EmSendCmdEx(uint8_t *resp, int respLen, bool correctionNeeded){
- return EmSendCmdExPar(resp, respLen, correctionNeeded, GetParity(resp, respLen));
+int EmSendCmdEx(uint8_t *resp, uint16_t respLen, bool correctionNeeded){
+ uint8_t par[MAX_PARITY_SIZE];
+ GetParity(resp, respLen, par);
+ return EmSendCmdExPar(resp, respLen, correctionNeeded, par);
}
-
-int EmSendCmd(uint8_t *resp, int respLen){
- return EmSendCmdExPar(resp, respLen, false, GetParity(resp, respLen));
+
+int EmSendCmd(uint8_t *resp, uint16_t respLen){
+ uint8_t par[MAX_PARITY_SIZE];
+ GetParity(resp, respLen, par);
+ return EmSendCmdExPar(resp, respLen, false, par);
}
-int EmSendCmdPar(uint8_t *resp, int respLen, uint32_t par){
+int EmSendCmdPar(uint8_t *resp, uint16_t respLen, uint8_t *par){
return EmSendCmdExPar(resp, respLen, false, par);
}
-bool EmLogTrace(uint8_t *reader_data, uint16_t reader_len, uint32_t reader_StartTime, uint32_t reader_EndTime, uint32_t reader_Parity,
- uint8_t *tag_data, uint16_t tag_len, uint32_t tag_StartTime, uint32_t tag_EndTime, uint32_t tag_Parity)
+bool EmLogTrace(uint8_t *reader_data, uint16_t reader_len, uint32_t reader_StartTime, uint32_t reader_EndTime, uint8_t *reader_Parity,
+ uint8_t *tag_data, uint16_t tag_len, uint32_t tag_StartTime, uint32_t tag_EndTime, uint8_t *tag_Parity)
{
- if (tracing) {
- // we cannot exactly measure the end and start of a received command from reader. However we know that the delay from
- // end of the received command to start of the tag's (simulated by us) answer is n*128+20 or n*128+84 resp.
- // with n >= 9. The start of the tags answer can be measured and therefore the end of the received command be calculated:
- uint16_t reader_modlen = reader_EndTime - reader_StartTime;
- uint16_t approx_fdt = tag_StartTime - reader_EndTime;
- uint16_t exact_fdt = (approx_fdt - 20 + 32)/64 * 64 + 20;
- reader_EndTime = tag_StartTime - exact_fdt;
- reader_StartTime = reader_EndTime - reader_modlen;
- if (!LogTrace(reader_data, reader_len, reader_StartTime, reader_Parity, TRUE)) {
- return FALSE;
- } else if (!LogTrace(NULL, 0, reader_EndTime, 0, TRUE)) {
- return FALSE;
- } else if (!LogTrace(tag_data, tag_len, tag_StartTime, tag_Parity, FALSE)) {
- return FALSE;
- } else {
- return (!LogTrace(NULL, 0, tag_EndTime, 0, FALSE));
- }
- } else {
- return TRUE;
- }
+ if (!tracing) return true;
+
+ // we cannot exactly measure the end and start of a received command from reader. However we know that the delay from
+ // end of the received command to start of the tag's (simulated by us) answer is n*128+20 or n*128+84 resp.
+ // with n >= 9. The start of the tags answer can be measured and therefore the end of the received command be calculated:
+ uint16_t reader_modlen = reader_EndTime - reader_StartTime;
+ uint16_t approx_fdt = tag_StartTime - reader_EndTime;
+ uint16_t exact_fdt = (approx_fdt - 20 + 32)/64 * 64 + 20;
+ reader_EndTime = tag_StartTime - exact_fdt;
+ reader_StartTime = reader_EndTime - reader_modlen;
+ if (!LogTrace(reader_data, reader_len, reader_StartTime, reader_EndTime, reader_Parity, TRUE)) {
+ return FALSE;
+ } else
+ return(!LogTrace(tag_data, tag_len, tag_StartTime, tag_EndTime, tag_Parity, FALSE));
}
//-----------------------------------------------------------------------------
// If a response is captured return TRUE
// If it takes too long return FALSE
//-----------------------------------------------------------------------------
-static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint16_t offset, int maxLen)
+static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receivedResponsePar, uint16_t offset)
{
uint16_t c;
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_LISTEN);
// Now get the answer from the card
- DemodReset();
- Demod.output = receivedResponse;
-
+ DemodInit(receivedResponse, receivedResponsePar);
+
// clear RXRDY:
uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
if(ManchesterDecoding(b, offset, 0)) {
NextTransferTime = MAX(NextTransferTime, Demod.endTime - (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER)/16 + FRAME_DELAY_TIME_PICC_TO_PCD);
return TRUE;
- } else if(c++ > iso14a_timeout) {
+ } else if (c++ > iso14a_timeout) {
return FALSE;
}
}
}
}
-void ReaderTransmitBitsPar(uint8_t* frame, int bits, uint32_t par, uint32_t *timing)
+void ReaderTransmitBitsPar(uint8_t* frame, uint16_t bits, uint8_t *par, uint32_t *timing)
{
-
- CodeIso14443aBitsAsReaderPar(frame,bits,par);
+ CodeIso14443aBitsAsReaderPar(frame, bits, par);
// Send command to tag
TransmitFor14443a(ToSend, ToSendMax, timing);
// Log reader command in trace buffer
if (tracing) {
- LogTrace(frame, nbytes(bits), LastTimeProxToAirStart*16 + DELAY_ARM2AIR_AS_READER, par, TRUE);
- LogTrace(NULL, 0, (LastTimeProxToAirStart + LastProxToAirDuration)*16 + DELAY_ARM2AIR_AS_READER, 0, TRUE);
+ LogTrace(frame, nbytes(bits), LastTimeProxToAirStart*16 + DELAY_ARM2AIR_AS_READER, (LastTimeProxToAirStart + LastProxToAirDuration)*16 + DELAY_ARM2AIR_AS_READER, par, TRUE);
}
}
-void ReaderTransmitPar(uint8_t* frame, int len, uint32_t par, uint32_t *timing)
+void ReaderTransmitPar(uint8_t* frame, uint16_t len, uint8_t *par, uint32_t *timing)
{
- ReaderTransmitBitsPar(frame,len*8,par, timing);
+ ReaderTransmitBitsPar(frame, len*8, par, timing);
}
-void ReaderTransmitBits(uint8_t* frame, int len, uint32_t *timing)
+void ReaderTransmitBits(uint8_t* frame, uint16_t len, uint32_t *timing)
{
- // Generate parity and redirect
- ReaderTransmitBitsPar(frame,len,GetParity(frame,len/8), timing);
+ // Generate parity and redirect
+ uint8_t par[MAX_PARITY_SIZE];
+ GetParity(frame, len/8, par);
+ ReaderTransmitBitsPar(frame, len, par, timing);
}
-void ReaderTransmit(uint8_t* frame, int len, uint32_t *timing)
+void ReaderTransmit(uint8_t* frame, uint16_t len, uint32_t *timing)
{
- // Generate parity and redirect
- ReaderTransmitBitsPar(frame,len*8,GetParity(frame,len), timing);
+ // Generate parity and redirect
+ uint8_t par[MAX_PARITY_SIZE];
+ GetParity(frame, len, par);
+ ReaderTransmitBitsPar(frame, len*8, par, timing);
}
-int ReaderReceiveOffset(uint8_t* receivedAnswer, uint16_t offset)
+int ReaderReceiveOffset(uint8_t* receivedAnswer, uint16_t offset, uint8_t *parity)
{
- if (!GetIso14443aAnswerFromTag(receivedAnswer,offset,160)) return FALSE;
+ if (!GetIso14443aAnswerFromTag(receivedAnswer,parity,offset)) return FALSE;
if (tracing) {
- LogTrace(receivedAnswer, Demod.len, Demod.startTime*16 - DELAY_AIR2ARM_AS_READER, Demod.parityBits, FALSE);
- LogTrace(NULL, 0, Demod.endTime*16 - DELAY_AIR2ARM_AS_READER, 0, FALSE);
+ LogTrace(receivedAnswer, Demod.len, Demod.startTime*16 - DELAY_AIR2ARM_AS_READER, Demod.endTime*16 - DELAY_AIR2ARM_AS_READER, parity, FALSE);
}
return Demod.len;
}
-int ReaderReceive(uint8_t* receivedAnswer)
+int ReaderReceive(uint8_t *receivedAnswer, uint8_t *parity)
{
- return ReaderReceiveOffset(receivedAnswer, 0);
-}
+ if (!GetIso14443aAnswerFromTag(receivedAnswer, parity, 0)) return FALSE;
-int ReaderReceivePar(uint8_t *receivedAnswer, uint32_t *parptr)
-{
- if (!GetIso14443aAnswerFromTag(receivedAnswer,0,160)) return FALSE;
if (tracing) {
- LogTrace(receivedAnswer, Demod.len, Demod.startTime*16 - DELAY_AIR2ARM_AS_READER, Demod.parityBits, FALSE);
- LogTrace(NULL, 0, Demod.endTime*16 - DELAY_AIR2ARM_AS_READER, 0, FALSE);
+ LogTrace(receivedAnswer, Demod.len, Demod.startTime*16 - DELAY_AIR2ARM_AS_READER, Demod.endTime*16 - DELAY_AIR2ARM_AS_READER, parity, FALSE);
}
- *parptr = Demod.parityBits;
return Demod.len;
}
* fills the uid pointer unless NULL
* fills resp_data unless NULL */
int iso14443a_select_card(byte_t* uid_ptr, iso14a_card_select_t* p_hi14a_card, uint32_t* cuid_ptr) {
- uint8_t wupa[] = { 0x52 }; // 0x26 - REQA 0x52 - WAKE-UP
- uint8_t sel_all[] = { 0x93,0x20 };
- uint8_t sel_uid[] = { 0x93,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
- uint8_t rats[] = { 0xE0,0x80,0x00,0x00 }; // FSD=256, FSDI=8, CID=0
- uint8_t* resp = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET); // was 3560 - tied to other size changes
- byte_t uid_resp[4];
- size_t uid_resp_len;
+ uint8_t halt[] = { 0x50 }; // HALT
+ uint8_t wupa[] = { 0x52 }; // WAKE-UP
+ //uint8_t reqa[] = { 0x26 }; // REQUEST A
+ uint8_t sel_all[] = { 0x93,0x20 };
+ uint8_t sel_uid[] = { 0x93,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
+ uint8_t rats[] = { 0xE0,0x80,0x00,0x00 }; // FSD=256, FSDI=8, CID=0
+ uint8_t *resp = ((uint8_t *)BigBuf) + RECV_RESP_OFFSET;
+ uint8_t *resp_par = ((uint8_t *)BigBuf) + RECV_RESP_PAR_OFFSET;
+
+ byte_t uid_resp[4];
+ size_t uid_resp_len;
uint8_t sak = 0x04; // cascade uid
int cascade_level = 0;
int len;
-
+
+ ReaderTransmit(halt,sizeof(halt), NULL);
+
// Broadcast for a card, WUPA (0x52) will force response from all cards in the field
- ReaderTransmitBitsPar(wupa,7,0, NULL);
+ ReaderTransmitBitsPar(wupa,7,0, NULL);
// Receive the ATQA
- if(!ReaderReceive(resp)) return 0;
+ if(!ReaderReceive(resp, resp_par)) return 0;
// Dbprintf("atqa: %02x %02x",resp[0],resp[1]);
if(p_hi14a_card) {
// SELECT_ALL
ReaderTransmit(sel_all,sizeof(sel_all), NULL);
- if (!ReaderReceive(resp)) return 0;
+ if (!ReaderReceive(resp, resp_par)) return 0;
if (Demod.collisionPos) { // we had a collision and need to construct the UID bit by bit
memset(uid_resp, 0, 4);
}
collision_answer_offset = uid_resp_bits%8;
ReaderTransmitBits(sel_uid, 16 + uid_resp_bits, NULL);
- if (!ReaderReceiveOffset(resp, collision_answer_offset)) return 0;
+ if (!ReaderReceiveOffset(resp, collision_answer_offset,resp_par)) return 0;
}
// finally, add the last bits and BCC of the UID
for (uint16_t i = collision_answer_offset; i < (Demod.len-1)*8; i++, uid_resp_bits++) {
ReaderTransmit(sel_uid,sizeof(sel_uid), NULL);
// Receive the SAK
- if (!ReaderReceive(resp)) return 0;
+ if (!ReaderReceive(resp, resp_par)) return 0;
sak = resp[0];
//Dbprintf("SAK: %02x",resp[0]);
// Test if more parts of the uid are comming
if ((sak & 0x04) /* && uid_resp[0] == 0x88 */) {
- // Remove first byte, 0x88 is not an UID byte, it CT, see page 3 of:
- // http://www.nxp.com/documents/application_note/AN10927.pdf
- // This was earlier:
- //memcpy(uid_resp, uid_resp + 1, 3);
- // But memcpy should not be used for overlapping arrays,
- // and memmove appears to not be available in the arm build.
- // So this has been replaced with a for-loop:
- for(int xx = 0; xx < 3; xx++)
- uid_resp[xx] = uid_resp[xx+1];
- uid_resp_len = 3;
+ // Remove first byte, 0x88 is not an UID byte, it CT, see page 3 of:
+ // http://www.nxp.com/documents/application_note/AN10927.pdf
+ // This was earlier:
+ //memcpy(uid_resp, uid_resp + 1, 3);
+ // But memcpy should not be used for overlapping arrays,
+ // and memmove appears to not be available in the arm build.
+ // Therefore:
+ uid_resp[0] = uid_resp[1];
+ uid_resp[1] = uid_resp[2];
+ uid_resp[2] = uid_resp[3];
+
+ uid_resp_len = 3;
}
if(uid_ptr) {
AppendCrc14443a(rats, 2);
ReaderTransmit(rats, sizeof(rats), NULL);
- if (!(len = ReaderReceive(resp))) return 0;
+ if (!(len = ReaderReceive(resp,resp_par))) return 0;
if(p_hi14a_card) {
memcpy(p_hi14a_card->ats, resp, sizeof(p_hi14a_card->ats));
iso14a_set_timeout(1050); // 10ms default 10*105 =
}
-int iso14_apdu(uint8_t * cmd, size_t cmd_len, void * data) {
+int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, void *data) {
+ uint8_t parity[MAX_PARITY_SIZE];
uint8_t real_cmd[cmd_len+4];
real_cmd[0] = 0x0a; //I-Block
// put block number into the PCB
AppendCrc14443a(real_cmd,cmd_len+2);
ReaderTransmit(real_cmd, cmd_len+4, NULL);
- size_t len = ReaderReceive(data);
+ size_t len = ReaderReceive(data, parity);
uint8_t * data_bytes = (uint8_t *) data;
if (!len)
return 0; //DATA LINK ERROR
{
iso14a_command_t param = c->arg[0];
uint8_t *cmd = c->d.asBytes;
- size_t len = c->arg[1] & 0xFFFF;
- size_t lenbits = c->arg[1] >> 16;
+ size_t len = c->arg[1];
+ size_t lenbits = c->arg[2];
uint32_t arg0 = 0;
byte_t buf[USB_CMD_DATA_SIZE];
+ uint8_t par[MAX_PARITY_SIZE];
if(param & ISO14A_CONNECT) {
iso14a_clear_trace();
if(param & ISO14A_APPEND_CRC) {
AppendCrc14443a(cmd,len);
len += 2;
- if(lenbits>0)
- lenbits += 16;
+ if (lenbits) lenbits += 16;
}
- if(lenbits>0) {
- ReaderTransmitBitsPar(cmd,lenbits,GetParity(cmd,lenbits/8), NULL);
+ if(lenbits>0) {
+ GetParity(cmd, lenbits/8, par);
+ ReaderTransmitBitsPar(cmd, lenbits, par, NULL);
} else {
ReaderTransmit(cmd,len, NULL);
}
- arg0 = ReaderReceive(buf);
+ arg0 = ReaderReceive(buf, par);
cmd_send(CMD_ACK,arg0,0,0,buf,sizeof(buf));
}
uint8_t mf_nr_ar[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
static uint8_t mf_nr_ar3;
- uint8_t* receivedAnswer = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET);
+ uint8_t* receivedAnswer = (((uint8_t *)BigBuf) + RECV_RESP_OFFSET);
+ uint8_t* receivedAnswerPar = (((uint8_t *)BigBuf) + RECV_RESP_PAR_OFFSET);
iso14a_clear_trace();
iso14a_set_tracing(TRUE);
byte_t nt_diff = 0;
- byte_t par = 0;
- //byte_t par_mask = 0xff;
+ uint8_t par[1] = {0}; // maximum 8 Bytes to be sent here, 1 byte parity is therefore enough
static byte_t par_low = 0;
bool led_on = TRUE;
- uint8_t uid[10];
+ uint8_t uid[10] ={0};
uint32_t cuid;
uint32_t nt = 0;
sync_cycles = 65536; // theory: Mifare Classic's random generator repeats every 2^16 cycles (and so do the nonces).
nt_attacked = 0;
nt = 0;
- par = 0;
+ par[0] = 0;
}
else {
// we were unsuccessful on a previous call. Try another READER nonce (first 3 parity bits remain the same)
- // nt_attacked = prng_successor(nt_attacked, 1);
mf_nr_ar3++;
mf_nr_ar[3] = mf_nr_ar3;
- par = par_low;
+ par[0] = par_low;
}
LED_A_ON();
LED_C_OFF();
- Dbprintf("Mifare: Before loopen");
for(uint16_t i = 0; TRUE; i++) {
WDT_HIT();
ReaderTransmit(mf_auth, sizeof(mf_auth), &sync_time);
// Receive the (4 Byte) "random" nonce
- if (!ReaderReceive(receivedAnswer)) {
+ if (!ReaderReceive(receivedAnswer, receivedAnswerPar)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Mifare: Couldn't receive tag nonce");
continue;
}
consecutive_resyncs = 0;
// Receive answer. This will be a 4 Bit NACK when the 8 parity bits are OK after decoding
- if (ReaderReceive(receivedAnswer))
+ if (ReaderReceive(receivedAnswer, receivedAnswerPar))
{
catch_up_cycles = 8; // the PRNG is delayed by 8 cycles due to the NAC (4Bits = 0x05 encrypted) transfer
if (nt_diff == 0)
{
- par_low = par & 0x07; // there is no need to check all parities for other nt_diff. Parity Bits for mf_nr_ar[0..2] won't change
+ par_low = par[0] & 0xE0; // there is no need to check all parities for other nt_diff. Parity Bits for mf_nr_ar[0..2] won't change
}
led_on = !led_on;
if(led_on) LED_B_ON(); else LED_B_OFF();
- par_list[nt_diff] = par;
+ par_list[nt_diff] = SwapBits(par[0], 8);
ks_list[nt_diff] = receivedAnswer[0] ^ 0x05;
// Test if the information is complete
nt_diff = (nt_diff + 1) & 0x07;
mf_nr_ar[3] = (mf_nr_ar[3] & 0x1F) | (nt_diff << 5);
- par = par_low;
+ par[0] = par_low;
} else {
if (nt_diff == 0 && first_try)
{
- par++;
+ par[0]++;
} else {
- par = (((par >> 3) + 1) << 3) | par_low;
+ par[0] = ((par[0] & 0x1F) + 1) | par_low;
}
}
}
int res;
uint32_t selTimer = 0;
uint32_t authTimer = 0;
- uint32_t par = 0;
- int len = 0;
+ uint16_t len = 0;
uint8_t cardWRBL = 0;
uint8_t cardAUTHSC = 0;
uint8_t cardAUTHKEY = 0xff; // no authentication
struct Crypto1State *pcs;
pcs = &mpcs;
uint32_t numReads = 0;//Counts numer of times reader read a block
- uint8_t* receivedCmd = eml_get_bigbufptr_recbuf();
- uint8_t *response = eml_get_bigbufptr_sendbuf();
+ uint8_t* receivedCmd = get_bigbufptr_recvcmdbuf();
+ uint8_t* receivedCmd_par = receivedCmd + MAX_FRAME_SIZE;
+ uint8_t* response = get_bigbufptr_recvrespbuf();
+ uint8_t* response_par = response + MAX_FRAME_SIZE;
uint8_t rATQA[] = {0x04, 0x00}; // Mifare classic 1k 4BUID
uint8_t rUIDBCC1[] = {0xde, 0xad, 0xbe, 0xaf, 0x62};
if (MF_DBGLEVEL >= 1) {
if (!_7BUID) {
- Dbprintf("4B UID: %02x%02x%02x%02x",rUIDBCC1[0] , rUIDBCC1[1] , rUIDBCC1[2] , rUIDBCC1[3]);
+ Dbprintf("4B UID: %02x%02x%02x%02x",
+ rUIDBCC1[0], rUIDBCC1[1], rUIDBCC1[2], rUIDBCC1[3]);
} else {
- Dbprintf("7B UID: (%02x)%02x%02x%02x%02x%02x%02x%02x",rUIDBCC1[0] , rUIDBCC1[1] , rUIDBCC1[2] , rUIDBCC1[3],rUIDBCC2[0],rUIDBCC2[1] ,rUIDBCC2[2] , rUIDBCC2[3]);
+ Dbprintf("7B UID: (%02x)%02x%02x%02x%02x%02x%02x%02x",
+ rUIDBCC1[0], rUIDBCC1[1], rUIDBCC1[2], rUIDBCC1[3],
+ rUIDBCC2[0], rUIDBCC2[1] ,rUIDBCC2[2], rUIDBCC2[3]);
}
}
//Now, get data
- res = EmGetCmd(receivedCmd, &len);
+ res = EmGetCmd(receivedCmd, &len, receivedCmd_par);
if (res == 2) { //Field is off!
cardSTATE = MFEMUL_NOFIELD;
LEDsoff();
case MFEMUL_NOFIELD:
case MFEMUL_HALTED:
case MFEMUL_IDLE:{
- LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parityBits, TRUE);
- LogTrace(NULL, 0, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, 0, TRUE);
+ LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
break;
}
case MFEMUL_SELECT1:{
if( len != 8)
{
cardSTATE_TO_IDLE();
- LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parityBits, TRUE);
- LogTrace(NULL, 0, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, 0, TRUE);
+ LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
break;
}
uint32_t ar = bytes_to_num(receivedCmd, 4);
- uint32_t nr= bytes_to_num(&receivedCmd[4], 4);
+ uint32_t nr = bytes_to_num(&receivedCmd[4], 4);
//Collect AR/NR
if(ar_nr_collected < 2){
// test if auth OK
if (cardRr != prng_successor(nonce, 64)){
- if (MF_DBGLEVEL >= 2) Dbprintf("AUTH FAILED. cardRr=%08x, succ=%08x",cardRr, prng_successor(nonce, 64));
+ if (MF_DBGLEVEL >= 2) Dbprintf("AUTH FAILED for sector %d with key %c. cardRr=%08x, succ=%08x",
+ cardAUTHSC, cardAUTHKEY == 0 ? 'A' : 'B',
+ cardRr, prng_successor(nonce, 64));
// Shouldn't we respond anything here?
// Right now, we don't nack or anything, which causes the
// reader to do a WUPA after a while. /Martin
// -- which is the correct response. /piwi
cardSTATE_TO_IDLE();
- LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parityBits, TRUE);
- LogTrace(NULL, 0, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, 0, TRUE);
+ LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
break;
}
}
case MFEMUL_SELECT2:{
if (!len) {
- LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parityBits, TRUE);
- LogTrace(NULL, 0, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, 0, TRUE);
+ LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
break;
}
if (len == 2 && (receivedCmd[0] == 0x95 && receivedCmd[1] == 0x20)) {
// i guess there is a command). go into the work state.
if (len != 4) {
- LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parityBits, TRUE);
- LogTrace(NULL, 0, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, 0, TRUE);
+ LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
break;
}
cardSTATE = MFEMUL_WORK;
case MFEMUL_WORK:{
if (len == 0) {
- LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parityBits, TRUE);
- LogTrace(NULL, 0, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, 0, TRUE);
+ LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
break;
}
}
if(len != 4) {
- LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parityBits, TRUE);
- LogTrace(NULL, 0, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, 0, TRUE);
+ LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
break;
}
}
emlGetMem(response, receivedCmd[1], 1);
AppendCrc14443a(response, 16);
- mf_crypto1_encrypt(pcs, response, 18, &par);
- EmSendCmdPar(response, 18, par);
+ mf_crypto1_encrypt(pcs, response, 18, response_par);
+ EmSendCmdPar(response, 18, response_par);
numReads++;
if(exitAfterNReads > 0 && numReads == exitAfterNReads) {
Dbprintf("%d reads done, exiting", numReads);
LED_C_OFF();
cardSTATE = MFEMUL_HALTED;
if (MF_DBGLEVEL >= 4) Dbprintf("--> HALTED. Selected time: %d ms", GetTickCount() - selTimer);
- LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parityBits, TRUE);
- LogTrace(NULL, 0, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, 0, TRUE);
+ LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
break;
}
// RATS
cardSTATE = MFEMUL_WORK;
} else {
cardSTATE_TO_IDLE();
- LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parityBits, TRUE);
- LogTrace(NULL, 0, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, 0, TRUE);
+ LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
}
break;
}
cardSTATE_TO_IDLE();
break;
}
- LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parityBits, TRUE);
- LogTrace(NULL, 0, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, 0, TRUE);
+ LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
cardINTREG = cardINTREG + ans;
cardSTATE = MFEMUL_WORK;
break;
cardSTATE_TO_IDLE();
break;
}
- LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parityBits, TRUE);
- LogTrace(NULL, 0, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, 0, TRUE);
+ LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
cardINTREG = cardINTREG - ans;
cardSTATE = MFEMUL_WORK;
break;
cardSTATE_TO_IDLE();
break;
}
- LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parityBits, TRUE);
- LogTrace(NULL, 0, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, 0, TRUE);
+ LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
cardSTATE = MFEMUL_WORK;
break;
}
// The length of a received command will in most cases be no more than 18 bytes.
// So 32 should be enough!
uint8_t *receivedCmd = (((uint8_t *)BigBuf) + RECV_CMD_OFFSET);
+ uint8_t *receivedCmdPar = ((uint8_t *)BigBuf) + RECV_CMD_PAR_OFFSET;
// The response (tag -> reader) that we're receiving.
- uint8_t *receivedResponse = (((uint8_t *)BigBuf) + RECV_RES_OFFSET);
-
+ uint8_t *receivedResponse = (((uint8_t *)BigBuf) + RECV_RESP_OFFSET);
+ uint8_t *receivedResponsePar = ((uint8_t *)BigBuf) + RECV_RESP_PAR_OFFSET;
+
// As we receive stuff, we copy it from receivedCmd or receivedResponse
// into trace, along with its length and other annotations.
//uint8_t *trace = (uint8_t *)BigBuf;
iso14443a_setup(FPGA_HF_ISO14443A_SNIFFER);
// Set up the demodulator for tag -> reader responses.
- Demod.output = receivedResponse;
+ DemodInit(receivedResponse, receivedResponsePar);
// Set up the demodulator for the reader -> tag commands
- Uart.output = receivedCmd;
+ UartInit(receivedCmd, receivedCmdPar);
// Setup for the DMA.
FpgaSetupSscDma((uint8_t *)dmaBuf, DMA_BUFFER_SIZE); // set transfer address and number of bytes. Start transfer.
uint8_t readerdata = (previous_data & 0xF0) | (*data >> 4);
if(MillerDecoding(readerdata, (sniffCounter-1)*4)) {
LED_C_INV();
- if (MfSniffLogic(receivedCmd, Uart.len, Uart.parityBits, Uart.bitCount, TRUE)) break;
+ if (MfSniffLogic(receivedCmd, Uart.len, Uart.parity, Uart.bitCount, TRUE)) break;
/* And ready to receive another command. */
UartReset();
if(ManchesterDecoding(tagdata, 0, (sniffCounter-1)*4)) {
LED_C_INV();
- if (MfSniffLogic(receivedResponse, Demod.len, Demod.parityBits, Demod.bitCount, FALSE)) break;
+ if (MfSniffLogic(receivedResponse, Demod.len, Demod.parity, Demod.bitCount, FALSE)) break;
// And ready to receive another response.
DemodReset();
#include "../include/common.h"
#include "mifaresniff.h"
-// mifare reader over DMA buffer (SnoopIso14443a())!!!
-#define MIFARE_BUFF_OFFSET 3560 // \/ \/ \/
-// card emulator memory
-#define EML_RESPONSES 4000
-#define CARD_MEMORY 6000
-#define CARD_MEMORY_LEN 4096
-
typedef struct {
enum {
DEMOD_UNSYNCD,
uint16_t bitCount;
uint16_t collisionPos;
uint16_t syncBit;
- uint32_t parityBits;
+ uint8_t parityBits;
+ uint8_t parityLen;
uint16_t shiftReg;
uint16_t samples;
uint16_t len;
uint32_t startTime, endTime;
uint8_t *output;
+ uint8_t *parity;
} tDemod;
typedef enum {
uint16_t byteCntMax;
uint16_t posCnt;
uint16_t syncBit;
- uint32_t parityBits;
+ uint8_t parityBits;
+ uint8_t parityLen;
uint16_t highCnt;
uint16_t twoBits;
uint32_t startTime, endTime;
uint8_t *output;
+ uint8_t *parity;
} tUart;
-//extern byte_t oddparity (const byte_t bt);
-extern uint32_t GetParity(const uint8_t *pbtCmd, int iLen);
+extern byte_t oddparity (const byte_t bt);
+extern void GetParity(const uint8_t *pbtCmd, uint16_t len, uint8_t *par);
extern void AppendCrc14443a(uint8_t *data, int len);
-extern void ReaderTransmit(uint8_t *frame, int len, uint32_t *timing);
-extern void ReaderTransmitBitsPar(uint8_t *frame, int bits, uint32_t par, uint32_t *timing);
-extern void ReaderTransmitPar(uint8_t *frame, int len, uint32_t par, uint32_t *timing);
-extern int ReaderReceive(uint8_t *receivedAnswer);
-extern int ReaderReceivePar(uint8_t *receivedAnswer, uint32_t *parptr);
+extern void ReaderTransmit(uint8_t *frame, uint16_t len, uint32_t *timing);
+extern void ReaderTransmitBitsPar(uint8_t *frame, uint16_t bits, uint8_t *par, uint32_t *timing);
+extern void ReaderTransmitPar(uint8_t *frame, uint16_t len, uint8_t *par, uint32_t *timing);
+extern int ReaderReceive(uint8_t *receivedAnswer, uint8_t *par);
extern void iso14443a_setup(uint8_t fpga_minor_mode);
-extern int iso14_apdu(uint8_t *cmd, size_t cmd_len, void *data);
+extern int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, void *data);
extern int iso14443a_select_card(uint8_t *uid_ptr, iso14a_card_select_t *resp_data, uint32_t *cuid_ptr);
extern void iso14a_set_trigger(bool enable);
extern void iso14a_set_timeout(uint32_t timeout);
-extern void iso14a_clear_tracelen();
+extern void iso14a_clear_trace();
extern void iso14a_set_tracing(bool enable);
#endif /* __ISO14443A_H */
//-----------------------------------------------------------------------------
void AcquireRawAdcSamplesIso15693(void)
{
- uint8_t *dest = mifare_get_bigbufptr();
+ uint8_t *dest = get_bigbufptr_recvrespbuf();
int c = 0;
int getNext = 0;
void RecordRawAdcSamplesIso15693(void)
{
- uint8_t *dest = mifare_get_bigbufptr();
+ uint8_t *dest = get_bigbufptr_recvrespbuf();
int c = 0;
int getNext = 0;
#include "crapto1.h"
#include "mifareutil.h"
+// 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
+#define T0 192
+
#define SHORT_COIL() LOW(GPIO_SSC_DOUT)
#define OPEN_COIL() HIGH(GPIO_SSC_DOUT)
// split into two routines so we can avoid timing issues after sending commands //
void DoAcquisition125k_internal(int trigger_threshold, bool silent)
{
- uint8_t *dest = mifare_get_bigbufptr();
- int n = 24000;
- int i = 0;
- memset(dest, 0x00, n);
+ uint8_t *dest = get_bigbufptr_recvrespbuf();
+ uint16_t i = 0;
+ memset(dest, 0x00, FREE_BUFFER_SIZE);
for(;;) {
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
continue;
else
trigger_threshold = -1;
- if (++i >= n) break;
+ if (++i >= FREE_BUFFER_SIZE) break;
}
}
if (!silent){
void ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1, uint8_t *command)
{
-
- /* Make sure the tag is reset */
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
+
+ /* Make sure the tag is reset */
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
SpinDelay(2500);
- int divisor_used = 95; // 125 KHz
+ int divisor = 95; // 125 KHz
// see if 'h' was specified
-
if (command[strlen((char *) command) - 1] == 'h')
- divisor_used = 88; // 134.8 KHz
+ divisor = 88; // 134.8 KHz
- FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used);
+ FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor);
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
// Give it a bit of time for the resonant antenna to settle.
- SpinDelay(50);
-
-
- // And a little more time for the tag to fully power up
SpinDelay(2000);
// Now set up the SSC to get the ADC samples that are now streaming at us.
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LED_D_OFF();
SpinDelayUs(delay_off);
- FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used);
+ FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor);
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
LED_D_ON();
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LED_D_OFF();
SpinDelayUs(delay_off);
- FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used);
-
+ FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor);
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
// now do the read
// PIO_SODR = Set Output Data Register
//#define LOW(x) AT91C_BASE_PIOA->PIO_CODR = (x)
//#define HIGH(x) AT91C_BASE_PIOA->PIO_SODR = (x)
-void SimulateTagLowFrequency(int period, int gap, int ledcontrol)
+void SimulateTagLowFrequency( uint16_t period, uint32_t gap, uint8_t ledcontrol)
{
- int i = 0;
+ LED_D_ON();
+
+ uint16_t i = 0;
+ uint8_t send = 0;
+
+ //int overflow = 0;
+ uint8_t *buf = (uint8_t *)BigBuf;
+
+ FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD);
+ FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
+ SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
+ RELAY_OFF();
+
+ // Configure output pin that is connected to the FPGA (for modulating)
+ AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT;
+ AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT;
+
+ SHORT_COIL();
+
+ // Enable Peripheral Clock for TIMER_CLOCK0, used to measure exact timing before answering
+ AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC0);
+
+ // Enable Peripheral Clock for TIMER_CLOCK1, used to capture edges of the reader frames
+ AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC1);
+ AT91C_BASE_PIOA->PIO_BSR = GPIO_SSC_FRAME;
+
+ // Disable timer during configuration
+ AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
+
+ // Capture mode, default timer source = MCK/2 (TIMER_CLOCK1), TIOA is external trigger,
+ // external trigger rising edge, load RA on rising edge of TIOA.
+ AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK | AT91C_TC_ETRGEDG_RISING | AT91C_TC_ABETRG | AT91C_TC_LDRA_RISING;
+
+ // Enable and reset counter
+ //AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
+ AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
+
+ while(!BUTTON_PRESS()) {
+ WDT_HIT();
+
+ // Receive frame, watch for at most T0*EOF periods
+ while (AT91C_BASE_TC1->TC_CV < T0 * 55) {
+
+ // Check if rising edge in modulation is detected
+ if(AT91C_BASE_TC1->TC_SR & AT91C_TC_LDRAS) {
+ // Retrieve the new timing values
+ //int ra = (AT91C_BASE_TC1->TC_RA/T0) + overflow;
+ //Dbprintf("Timing value - %d %d", ra, overflow);
+ //overflow = 0;
+
+ // Reset timer every frame, we have to capture the last edge for timing
+ AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
+ send = 1;
+
+ LED_B_ON();
+ }
+ }
+
+ if ( send ) {
+ // Disable timer 1 with external trigger to avoid triggers during our own modulation
+ AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
+
+ // Wait for HITAG_T_WAIT_1 carrier periods after the last reader bit,
+ // not that since the clock counts since the rising edge, but T_Wait1 is
+ // with respect to the falling edge, we need to wait actually (T_Wait1 - T_Low)
+ // periods. The gap time T_Low varies (4..10). All timer values are in
+ // terms of T0 units
+ while(AT91C_BASE_TC0->TC_CV < T0 * 16 );
+
+ // datat kommer in som 1 bit för varje position i arrayn
+ for(i = 0; i < period; ++i) {
+
+ // Reset clock for the next bit
+ AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG;
+
+ if ( buf[i] > 0 )
+ HIGH(GPIO_SSC_DOUT);
+ else
+ LOW(GPIO_SSC_DOUT);
+
+ while(AT91C_BASE_TC0->TC_CV < T0 * 1 );
+ }
+ // Drop modulation
+ LOW(GPIO_SSC_DOUT);
+
+ // Enable and reset external trigger in timer for capturing future frames
+ AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
+ LED_B_OFF();
+ }
+
+ send = 0;
+
+ // Save the timer overflow, will be 0 when frame was received
+ //overflow += (AT91C_BASE_TC1->TC_CV/T0);
+
+ // Reset the timer to restart while-loop that receives frames
+ AT91C_BASE_TC1->TC_CCR = AT91C_TC_SWTRG;
+ }
+
+ LED_B_OFF();
+ LED_D_OFF();
+ AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
+ AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+
+ DbpString("Sim Stopped");
+}
+
+
+void SimulateTagLowFrequencyA(int len, int gap)
+{
+ //Dbprintf("LEN %d || Gap %d",len, gap);
+
uint8_t *buf = (uint8_t *)BigBuf;
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
- FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT);
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_TOGGLE_MODE); // new izsh toggle mode!
// 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.
FpgaSetupSsc();
+ SpinDelay(5);
- // Configure output and enable pin that is connected to the FPGA (for modulating)
- // AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT | GPIO_SSC_CLK; // (PIO_PER) PIO Enable Register
- // AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; // (PIO_OER) Output Enable Register
- // AT91C_BASE_PIOA->PIO_ODR = GPIO_SSC_CLK; // (PIO_ODR) Output Disable Register
-
- AT91C_BASE_PIOA->PIO_OER = GPIO_PCK0;
+ AT91C_BASE_SSC->SSC_THR = 0x00;
+ int i = 0;
while(!BUTTON_PRESS()) {
WDT_HIT();
+ if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
+
+ if ( buf[i] > 0 )
+ AT91C_BASE_SSC->SSC_THR = 0x43;
+ else
+ AT91C_BASE_SSC->SSC_THR = 0x00;
- // PIO_PDSR = Pin Data Status Register
- // GPIO_SSC_CLK = SSC Transmit Clock
- // wait ssp_clk == high
- while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) {
- if(BUTTON_PRESS()) {
- DbpString("Stopped at 0");
- return;
- }
- WDT_HIT();
- }
-
- if ( buf[i] > 0 ){
- OPEN_COIL();
- } else {
- SHORT_COIL();
- }
-
- DbpString("Enter Sim3");
- // wait ssp_clk == low
- while( (AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK) ) {
- if(BUTTON_PRESS()) {
- DbpString("stopped at 1");
- return;
+ ++i;
+ LED_A_ON();
+ if (i >= len){
+ i = 0;
}
- WDT_HIT();
}
- DbpString("Enter Sim4 ");
- //SpinDelayUs(512);
-
- ++i;
- if(i == period) {
- i = 0;
- if (gap) {
- SHORT_COIL();
- SpinDelay(gap);
- }
+ if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
+ volatile uint32_t r = AT91C_BASE_SSC->SSC_RHR;
+ (void)r;
+ LED_A_OFF();
}
}
- DbpString("Stopped");
- return;
+ DbpString("lf simulate stopped");
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
}
#define DEBUG_FRAME_CONTENTS 1
}
// compose fc/8 fc/10 waveform
-static void fc(int c, int *n) {
+static void fc(int c, uint16_t *n) {
uint8_t *dest = (uint8_t *)BigBuf;
int idx;
// prepare a waveform pattern in the buffer based on the ID given then
// simulate a HID tag until the button is pressed
-void CmdHIDsimTAG(int hi, int lo, int ledcontrol)
+void CmdHIDsimTAG(int hi, int lo, uint8_t ledcontrol)
{
- int n=0, i=0;
+ uint16_t n=0, i=0;
/*
HID tag bitstream format
The tag contains a 44bit unique code. This is sent out MSB first in sets of 4 bits
}
-size_t aggregate_bits(uint8_t *dest,size_t size, uint8_t h2l_crossing_value,uint8_t l2h_crossing_value, uint8_t maxConsequtiveBits )
+size_t aggregate_bits(uint8_t *dest,size_t size, uint8_t h2l_crossing_value,uint8_t l2h_crossing_value, uint8_t maxConsequtiveBits, uint8_t invert )
{
uint8_t lastval=dest[0];
uint32_t idx=0;
continue;
}
//if lastval was 1, we have a 1->0 crossing
- if ( dest[idx-1] ) {
+ if ( dest[idx-1]==1 ) {
n=(n+1) / h2l_crossing_value;
} else {// 0->1 crossing
n=(n+1) / l2h_crossing_value;
if(n < maxConsequtiveBits)
{
- memset(dest+numBits, dest[idx-1] , n);
+ if ( invert==0)
+ memset(dest+numBits, dest[idx-1] , n);
+ else
+ memset(dest+numBits, dest[idx-1]^1 , n);
+
numBits += n;
}
n=0;
// loop to capture raw HID waveform then FSK demodulate the TAG ID from it
void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
{
- uint8_t *dest = (uint8_t *)BigBuf;
+ uint8_t *dest = get_bigbufptr_recvrespbuf();
size_t size=0,idx=0; //, found=0;
- uint32_t hi2=0, hi=0, lo=0;
+ uint32_t hi2=0, hi=0, lo=0;
// Configure to go in 125Khz listen mode
LFSetupFPGAForADC(0, true);
if (ledcontrol) LED_A_ON();
DoAcquisition125k_internal(-1,true);
- size = sizeof(BigBuf);
// FSK demodulator
- size = fsk_demod(dest, size);
+ size = fsk_demod(dest, FREE_BUFFER_SIZE);
// we now have a set of cycle counts, loop over previous results and aggregate data into bit patterns
// 1->0 : fc/8 in sets of 6
// 0->1 : fc/10 in sets of 5
- size = aggregate_bits(dest,size, 6,5,5);
-
- WDT_HIT();
+ // do not invert
+ size = aggregate_bits(dest,size, 6,5,5,0);
// final loop, go over previously decoded manchester data and decode into usable tag ID
// 111000 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0
{
// Keep going until next frame marker (or error)
// Shift in a bit. Start by shifting high registers
- hi2=(hi2<<1)|(hi>>31);
+ hi2=(hi2<<1)|(hi>>31);
hi=(hi<<1)|(lo>>31);
//Then, shift in a 0 or one into low
if (dest[idx] && !dest[idx+1]) // 1 0
// Hopefully, we read a tag and hit upon the next frame marker
if(idx + sizeof(frame_marker_mask) < size)
{
- if ( memcmp(dest+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0)
- {
- if (hi2 != 0){
- Dbprintf("TAG ID: %x%08x%08x (%d)",
- (unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF);
- }
- else {
- Dbprintf("TAG ID: %x%08x (%d)",
- (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF);
+ if ( memcmp(dest+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0)
+ {
+ if (hi2 != 0){
+ Dbprintf("TAG ID: %x%08x%08x (%d)",
+ (unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF);
+ }
+ else {
+ Dbprintf("TAG ID: %x%08x (%d)",
+ (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF);
+ }
}
}
- }
-
// reset
hi2 = hi = lo = 0;
numshifts = 0;
- }else
- {
+ } else {
idx++;
}
}
void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol)
{
- uint8_t *dest = (uint8_t *)BigBuf;
-
+ uint8_t *dest = get_bigbufptr_recvrespbuf();
+
size_t size=0, idx=0;
uint32_t code=0, code2=0;
-
+ uint8_t isFinish = 0;
+
// Configure to go in 125Khz listen mode
LFSetupFPGAForADC(0, true);
- while(!BUTTON_PRESS()) {
+ while(!BUTTON_PRESS() & !isFinish) {
+
WDT_HIT();
+
if (ledcontrol) LED_A_ON();
DoAcquisition125k_internal(-1,true);
- size = sizeof(BigBuf);
// FSK demodulator
- size = fsk_demod(dest, size);
+ size = fsk_demod(dest, FREE_BUFFER_SIZE);
// we now have a set of cycle counts, loop over previous results and aggregate data into bit patterns
// 1->0 : fc/8 in sets of 7
// 0->1 : fc/10 in sets of 6
- size = aggregate_bits(dest, size, 7,6,13);
-
- WDT_HIT();
-
+ size = aggregate_bits(dest, size, 7,6,13,1); //13 max Consecutive should be ok as most 0s in row should be 10 for init seq - invert bits
+
+ //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
+
uint8_t mask[] = {0,0,0,0,0,0,0,0,0,1};
- for( idx=0; idx < size - 64; idx++) {
-
- if ( memcmp(dest + idx, mask, sizeof(mask)) ) continue;
-
- Dbprintf("%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]);
- Dbprintf("%d%d%d%d%d%d%d%d",dest[idx+8], dest[idx+9], dest[idx+10],dest[idx+11],dest[idx+12],dest[idx+13],dest[idx+14],dest[idx+15]);
- Dbprintf("%d%d%d%d%d%d%d%d",dest[idx+16],dest[idx+17],dest[idx+18],dest[idx+19],dest[idx+20],dest[idx+21],dest[idx+22],dest[idx+23]);
- Dbprintf("%d%d%d%d%d%d%d%d",dest[idx+24],dest[idx+25],dest[idx+26],dest[idx+27],dest[idx+28],dest[idx+29],dest[idx+30],dest[idx+31]);
- Dbprintf("%d%d%d%d%d%d%d%d",dest[idx+32],dest[idx+33],dest[idx+34],dest[idx+35],dest[idx+36],dest[idx+37],dest[idx+38],dest[idx+39]);
- Dbprintf("%d%d%d%d%d%d%d%d",dest[idx+40],dest[idx+41],dest[idx+42],dest[idx+43],dest[idx+44],dest[idx+45],dest[idx+46],dest[idx+47]);
- Dbprintf("%d%d%d%d%d%d%d%d",dest[idx+48],dest[idx+49],dest[idx+50],dest[idx+51],dest[idx+52],dest[idx+53],dest[idx+54],dest[idx+55]);
- Dbprintf("%d%d%d%d%d%d%d%d",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);
+ for( idx=0; idx < (size - 64); idx++) {
+ if ( memcmp(dest + idx, mask, sizeof(mask))==0) {
+ //frame marker found
+ 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);
+ short version = bytebits_to_byte(dest+idx+28,8); //14,4
+ char facilitycode = bytebits_to_byte(dest+idx+19,8) ;
+ uint16_t number = (bytebits_to_byte(dest+idx+37,8)<<8)|(bytebits_to_byte(dest+idx+46,8)); //36,9
+
+ Dbprintf("XSF(%02d)%02x:%d (%08x%08x)",version,facilitycode,number,code,code2);
- short version = bytebits_to_byte(dest+idx+14,4);
- char unknown = bytebits_to_byte(dest+idx+19,8) ;
- uint16_t number = bytebits_to_byte(dest+idx+36,9);
-
- Dbprintf("XSF(%02d)%02x:%d (%08x%08x)",version,unknown,number,code,code2);
- if (ledcontrol) LED_D_OFF();
-
- // if we're only looking for one tag
- if (findone){
- LED_A_OFF();
- return;
+ // if we're only looking for one tag
+ if (findone){
+ if (ledcontrol) LED_A_OFF();
+ isFinish = 1;
+ break;
+ }
+ }
}
- }
- WDT_HIT();
+ WDT_HIT();
}
DbpString("Stopped");
if (ledcontrol) LED_A_OFF();
// Read one card block in page 0
void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode)
{
- uint8_t *dest = mifare_get_bigbufptr();
+ uint8_t *dest = get_bigbufptr_recvrespbuf();
uint16_t bufferlength = T55xx_SAMPLES_SIZE;
uint32_t i = 0;
for(;;) {
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
AT91C_BASE_SSC->SSC_THR = 0x43;
+ //AT91C_BASE_SSC->SSC_THR = 0xff;
LED_D_ON();
}
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
// Read card traceability data (page 1)
void T55xxReadTrace(void){
- uint8_t *dest = mifare_get_bigbufptr();
+ uint8_t *dest = get_bigbufptr_recvrespbuf();
uint16_t bufferlength = T55xx_SAMPLES_SIZE;
- int i=0;
+ uint32_t i = 0;
// Clear destination buffer before sending the command 0x80 = average
memset(dest, 0x80, bufferlength);
void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode) {
- uint8_t *dest = mifare_get_bigbufptr();
+ uint8_t *dest = get_bigbufptr_recvrespbuf();
uint16_t bufferlength = 12000;
uint32_t i = 0;
}\r
\r
// Return 1 if the nonce is invalid else return 0\r
-int valid_nonce(uint32_t Nt, uint32_t NtEnc, uint32_t Ks1, byte_t * parity) {\r
+int valid_nonce(uint32_t Nt, uint32_t NtEnc, uint32_t Ks1, uint8_t * parity) {\r
return ((oddparity((Nt >> 24) & 0xFF) == ((parity[0]) ^ oddparity((NtEnc >> 24) & 0xFF) ^ BIT(Ks1,16))) & \\r
(oddparity((Nt >> 16) & 0xFF) == ((parity[1]) ^ oddparity((NtEnc >> 16) & 0xFF) ^ BIT(Ks1,8))) & \\r
(oddparity((Nt >> 8) & 0xFF) == ((parity[2]) ^ oddparity((NtEnc >> 8) & 0xFF) ^ BIT(Ks1,0)))) ? 1 : 0;\r
uint16_t davg;\r
static uint16_t dmin, dmax;\r
uint8_t uid[10];\r
- uint32_t cuid, nt1, nt2, nttmp, nttest, par, ks1;\r
+ uint32_t cuid, nt1, nt2, nttmp, nttest, ks1;\r
+ uint8_t par[1];\r
uint32_t target_nt[2], target_ks[2];\r
\r
uint8_t par_array[4];\r
struct Crypto1State mpcs = {0, 0};\r
struct Crypto1State *pcs;\r
pcs = &mpcs;\r
- uint8_t* receivedAnswer = mifare_get_bigbufptr();\r
+ uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();\r
\r
uint32_t auth1_time, auth2_time;\r
static uint16_t delta_time;\r
WDT_HIT();\r
\r
davg = dmax = 0;\r
- dmin = 2000;\r
+ dmin = 2000; \r
delta_time = 0;\r
\r
for (rtr = 0; rtr < 17; rtr++) {\r
continue;\r
};\r
\r
- nttmp = prng_successor(nt1, 140); //NXP Mifare is typical around 840,but for some unlicensed/compatible mifare card this can be 160\r
+ nttmp = prng_successor(nt1, 100); //NXP Mifare is typical around 840,but for some unlicensed/compatible mifare card this can be 160\r
for (i = 141; i < 1200; i++) {\r
nttmp = prng_successor(nttmp, 1);\r
if (nttmp == nt2) {break;}\r
\r
// nested authentication\r
auth2_time = auth1_time + delta_time;\r
- len = mifare_sendcmd_shortex(pcs, AUTH_NESTED, 0x60 + (targetKeyType & 0x01), targetBlockNo, receivedAnswer, &par, &auth2_time);\r
+ len = mifare_sendcmd_shortex(pcs, AUTH_NESTED, 0x60 + (targetKeyType & 0x01), targetBlockNo, receivedAnswer, par, &auth2_time);\r
if (len != 4) {\r
if (MF_DBGLEVEL >= 1) Dbprintf("Nested: Auth2 error len=%d", len);\r
continue;\r
};\r
\r
nt2 = bytes_to_num(receivedAnswer, 4); \r
- if (MF_DBGLEVEL >= 3) Dbprintf("Nonce#%d: Testing nt1=%08x nt2enc=%08x nt2par=%02x", i+1, nt1, nt2, par);\r
+ if (MF_DBGLEVEL >= 3) Dbprintf("Nonce#%d: Testing nt1=%08x nt2enc=%08x nt2par=%02x", i+1, nt1, nt2, par[0]);\r
\r
// Parity validity check\r
for (j = 0; j < 4; j++) {\r
- par_array[j] = (oddparity(receivedAnswer[j]) != ((par & 0x08) >> 3));\r
- par = par << 1;\r
+ par_array[j] = (oddparity(receivedAnswer[j]) != ((par[0] >> (7-j)) & 0x01));\r
}\r
\r
ncount = 0;\r
// ----------------------------- crypto1 destroy\r
crypto1_destroy(pcs);\r
\r
- // add trace trailer\r
- memset(uid, 0x44, 4);\r
- LogTrace(uid, 4, 0, 0, TRUE);\r
-\r
byte_t buf[4 + 4 * 4];\r
memcpy(buf, &cuid, 4);\r
memcpy(buf+4, &target_nt[0], 4);\r
uint32_t cuid;\r
\r
memset(uid, 0x00, 10);\r
- uint8_t* receivedAnswer = mifare_get_bigbufptr();\r
+ uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();\r
+ uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;\r
\r
if (workFlags & 0x08) {\r
// clear trace\r
\r
// reset chip\r
if (needWipe){\r
- ReaderTransmitBitsPar(wupC1,7,0, NULL);\r
- if(!ReaderReceive(receivedAnswer) || (receivedAnswer[0] != 0x0a)) {\r
+ ReaderTransmitBitsPar(wupC1,7,0, NULL);\r
+ if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {\r
if (MF_DBGLEVEL >= 1) Dbprintf("wupC1 error");\r
break;\r
};\r
\r
ReaderTransmit(wipeC, sizeof(wipeC), NULL);\r
- if(!ReaderReceive(receivedAnswer) || (receivedAnswer[0] != 0x0a)) {\r
+ if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {\r
if (MF_DBGLEVEL >= 1) Dbprintf("wipeC error");\r
break;\r
};\r
\r
// write block\r
if (workFlags & 0x02) {\r
- ReaderTransmitBitsPar(wupC1,7,0, NULL);\r
- if(!ReaderReceive(receivedAnswer) || (receivedAnswer[0] != 0x0a)) {\r
+ ReaderTransmitBitsPar(wupC1,7,0, NULL);\r
+ if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {\r
if (MF_DBGLEVEL >= 1) Dbprintf("wupC1 error");\r
break;\r
};\r
\r
ReaderTransmit(wupC2, sizeof(wupC2), NULL);\r
- if(!ReaderReceive(receivedAnswer) || (receivedAnswer[0] != 0x0a)) {\r
+ if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {\r
if (MF_DBGLEVEL >= 1) Dbprintf("wupC2 error");\r
break;\r
};\r
}\r
\r
- if ((mifare_sendcmd_short(NULL, 0, 0xA0, blockNo, receivedAnswer, NULL) != 1) || (receivedAnswer[0] != 0x0a)) {\r
+ if ((mifare_sendcmd_short(NULL, 0, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 1) || (receivedAnswer[0] != 0x0a)) {\r
if (MF_DBGLEVEL >= 1) Dbprintf("write block send command error");\r
break;\r
};\r
AppendCrc14443a(d_block, 16);\r
\r
ReaderTransmit(d_block, sizeof(d_block), NULL);\r
- if ((ReaderReceive(receivedAnswer) != 1) || (receivedAnswer[0] != 0x0a)) {\r
+ if ((ReaderReceive(receivedAnswer, receivedAnswerPar) != 1) || (receivedAnswer[0] != 0x0a)) {\r
if (MF_DBGLEVEL >= 1) Dbprintf("write block send data error");\r
break;\r
}; \r
uint32_t cuid = 0;\r
\r
memset(data, 0x00, 18);\r
- uint8_t* receivedAnswer = mifare_get_bigbufptr();\r
+ uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();\r
+ uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;\r
\r
if (workFlags & 0x08) {\r
// clear trace\r
while (true) {\r
if (workFlags & 0x02) {\r
ReaderTransmitBitsPar(wupC1,7,0, NULL);\r
- if(!ReaderReceive(receivedAnswer) || (receivedAnswer[0] != 0x0a)) {\r
+ if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {\r
if (MF_DBGLEVEL >= 1) Dbprintf("wupC1 error");\r
break;\r
};\r
\r
ReaderTransmit(wupC2, sizeof(wupC2), NULL);\r
- if(!ReaderReceive(receivedAnswer) || (receivedAnswer[0] != 0x0a)) {\r
+ if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {\r
if (MF_DBGLEVEL >= 1) Dbprintf("wupC2 error");\r
break;\r
};\r
}\r
\r
// read block\r
- if ((mifare_sendcmd_short(NULL, 0, 0x30, blockNo, receivedAnswer, NULL) != 18)) {\r
+ if ((mifare_sendcmd_short(NULL, 0, 0x30, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 18)) {\r
if (MF_DBGLEVEL >= 1) Dbprintf("read block send command error");\r
break;\r
};\r
#define MAX_APPLICATION_COUNT 28
#define MAX_FILE_COUNT 16
-#define MAX_FRAME_SIZE 60
+#define MAX_DESFIRE_FRAME_SIZE 60
#define NOT_YET_AUTHENTICATED 255
-#define FRAME_PAYLOAD_SIZE (MAX_FRAME_SIZE - 5)
+#define FRAME_PAYLOAD_SIZE (MAX_DESFIRE_FRAME_SIZE - 5)
+#define RECEIVE_SIZE 64
// the block number for the ISO14443-4 PCB
uint8_t pcb_blocknum = 0;
*/
uint8_t flags = arg0;
size_t datalen = arg1;
- uint8_t resp[RECV_RES_SIZE];
+ uint8_t resp[RECEIVE_SIZE];
memset(resp,0,sizeof(resp));
if (MF_DBGLEVEL >= 4) {
//uint8_t new_key_data8[8] = { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77};
//uint8_t new_key_data16[16] = { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF};
- //uint8_t* bigbuffer = mifare_get_bigbufptr();
+ //uint8_t* bigbuffer = get_bigbufptr_recvrespbuf();
uint8_t resp[256] = {0x00};
uint8_t IV[16] = {0x00};
size_t wrappedLen = 0;
uint8_t wCmd[USB_CMD_DATA_SIZE] = {0};
+ uint8_t *resp = ((uint8_t *)BigBuf) + RECV_RESP_OFFSET;
+ uint8_t *resp_par = ((uint8_t *)BigBuf) + RECV_RESP_PAR_OFFSET;
+
wrappedLen = CreateAPDU( cmd, cmd_len, wCmd);
if (MF_DBGLEVEL >= 4) {
}
ReaderTransmit( wCmd, wrappedLen, NULL);
- status = ReaderReceive(dataout);
+ status = ReaderReceive(resp, resp_par);
if( status == 0x00){
if (MF_DBGLEVEL >= 4) {
// if we received an I- or R(ACK)-Block with a block number equal to the
// current block number, toggle the current block number
else if (status >= 4 // PCB+CID+CRC = 4 bytes
- && ((dataout[0] & 0xC0) == 0 // I-Block
- || (dataout[0] & 0xD0) == 0x80) // R-Block with ACK bit set to 0
- && (dataout[0] & 0x01) == pcb_blocknum) // equal block numbers
+ && ((resp[0] & 0xC0) == 0 // I-Block
+ || (resp[0] & 0xD0) == 0x80) // R-Block with ACK bit set to 0
+ && (resp[0] & 0x01) == pcb_blocknum) // equal block numbers
{
pcb_blocknum ^= 1; //toggle next block
}
+ // copy response to
+ dataout = resp;
return status;
}
return FALSE;\r
}\r
\r
-bool RAMFUNC MfSniffLogic(const uint8_t *data, uint16_t len, uint32_t parity, uint16_t bitCnt, bool reader) {\r
+bool RAMFUNC MfSniffLogic(const uint8_t *data, uint16_t len, uint8_t *parity, uint16_t bitCnt, bool reader) {\r
\r
if (reader && (len == 1) && (bitCnt == 7)) { // reset on 7-Bit commands from reader\r
sniffState = SNF_INIT;\r
sniffBuf[11] = sniffSAK;\r
sniffBuf[12] = 0xFF;\r
sniffBuf[13] = 0xFF;\r
- LogTrace(sniffBuf, 14, 0, parity, true);\r
+ LogTrace(sniffBuf, 14, 0, 0, NULL, TRUE);\r
} // intentionally no break;\r
case SNF_CARD_CMD:{ \r
- LogTrace(data, len, 0, parity, true);\r
+ LogTrace(data, len, 0, 0, NULL, TRUE);\r
sniffState = SNF_CARD_RESP;\r
timerData = GetTickCount();\r
break;\r
}\r
case SNF_CARD_RESP:{\r
- LogTrace(data, len, 0, parity, false);\r
+ LogTrace(data, len, 0, 0, NULL, FALSE);\r
sniffState = SNF_CARD_CMD;\r
timerData = GetTickCount();\r
break;\r
#define SNF_UID_7 0\r
\r
bool MfSniffInit(void);\r
-bool RAMFUNC MfSniffLogic(const uint8_t * data, uint16_t len, uint32_t parity, uint16_t bitCnt, bool reader);\r
+bool RAMFUNC MfSniffLogic(const uint8_t *data, uint16_t len, uint8_t *parity, uint16_t bitCnt, bool reader);\r
bool RAMFUNC MfSniffSend(uint16_t maxTimeoutMs);\r
bool intMfSniffSend();\r
bool MfSniffEnd(void);\r
int MF_DBGLEVEL = MF_DBG_ALL;\r
\r
// memory management\r
-uint8_t* mifare_get_bigbufptr(void) {\r
- return (((uint8_t *)BigBuf) + MIFARE_BUFF_OFFSET); // was 3560 - tied to other size changes\r
+uint8_t* get_bigbufptr_recvrespbuf(void) {\r
+ return (((uint8_t *)BigBuf) + RECV_RESP_OFFSET);\r
}\r
-uint8_t* eml_get_bigbufptr_sendbuf(void) {\r
+uint8_t* get_bigbufptr_recvcmdbuf(void) {\r
return (((uint8_t *)BigBuf) + RECV_CMD_OFFSET); \r
}\r
-uint8_t* eml_get_bigbufptr_recbuf(void) {\r
- return (((uint8_t *)BigBuf) + MIFARE_BUFF_OFFSET);\r
-}\r
-uint8_t* eml_get_bigbufptr_cardmem(void) {\r
- return (((uint8_t *)BigBuf) + CARD_MEMORY);\r
+uint8_t* get_bigbufptr_emlcardmem(void) {\r
+ return (((uint8_t *)BigBuf) + CARD_MEMORY_OFFSET);\r
}\r
\r
// crypto1 helpers\r
return;\r
}\r
\r
-void mf_crypto1_encrypt(struct Crypto1State *pcs, uint8_t *data, int len, uint32_t *par) {\r
+void mf_crypto1_encrypt(struct Crypto1State *pcs, uint8_t *data, uint16_t len, uint8_t *par) {\r
uint8_t bt = 0;\r
int i;\r
- uint32_t mltpl = 1 << (len - 1); // for len=18 it=0x20000\r
- *par = 0;\r
+ par[0] = 0;\r
+ \r
for (i = 0; i < len; i++) {\r
bt = data[i];\r
data[i] = crypto1_byte(pcs, 0x00, 0) ^ data[i];\r
- *par = (*par >> 1) | ( ((filter(pcs->odd) ^ oddparity(bt)) & 0x01) * mltpl );\r
+ if((i&0x0007) == 0) \r
+ par[i>>3] = 0;\r
+ par[i>>3] |= (((filter(pcs->odd) ^ oddparity(bt)) & 0x01)<<(7-(i&0x0007)));\r
} \r
return;\r
}\r
}\r
\r
// send commands\r
-int mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t* answer, uint32_t *timing)\r
+int mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing)\r
{\r
- return mifare_sendcmd_shortex(pcs, crypted, cmd, data, answer, NULL, timing);
+ return mifare_sendcmd_shortex(pcs, crypted, cmd, data, answer, answer_parity, timing);
}
-int mifare_sendcmd_short_special(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t* data, uint8_t* answer, uint8_t *timing)
+int mifare_sendcmd_short_special(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t* data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing)
{
- uint8_t dcmd[8];
- dcmd[0] = cmd;
- memcpy(dcmd+1,data,5);
+ uint8_t dcmd[8];
+ dcmd[0] = cmd;
+ memcpy(dcmd+1,data,5);\r
+
AppendCrc14443a(dcmd, 6);
ReaderTransmit(dcmd, sizeof(dcmd), NULL);
- int len = ReaderReceive(answer);
+ int len = ReaderReceive(answer, answer_parity);
if(!len) {
if (MF_DBGLEVEL >= 1) Dbprintf("Authentication failed. Card timeout.");
return 2;
return len;\r
}\r
\r
-int mifare_sendcmd_short_mfucauth(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t* data, uint8_t* answer, uint32_t *timing)\r
+int mifare_sendcmd_short_mfucauth(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing)\r
{\r
uint8_t dcmd[19];\r
int len; \r
AppendCrc14443a(dcmd, 17);\r
\r
ReaderTransmit(dcmd, sizeof(dcmd), timing);\r
- len = ReaderReceive(answer);\r
+ len = ReaderReceive(answer, answer_parity);\r
if(!len) {\r
if (MF_DBGLEVEL >= 1) Dbprintf("Authentication failed. Card timeout.");\r
- len = ReaderReceive(answer);\r
+ len = ReaderReceive(answer,answer_parity);\r
}\r
if(len==1) {\r
if (MF_DBGLEVEL >= 1) Dbprintf("NAK - Authentication failed.");\r
return len;
}
-int mifare_sendcmd_shortex(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t* answer, uint32_t * parptr, uint32_t *timing)
+int mifare_sendcmd_shortex(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing)
{
uint8_t dcmd[4], ecmd[4];
- uint32_t pos, par, res;\r
-\r
+ uint16_t pos, res;\r
+ uint8_t par[1]; // 1 Byte parity is enough here\r
dcmd[0] = cmd;\r
dcmd[1] = data;\r
AppendCrc14443a(dcmd, 2);\r
memcpy(ecmd, dcmd, sizeof(dcmd));\r
\r
if (crypted) {\r
- par = 0;\r
+ par[0] = 0;\r
for (pos = 0; pos < 4; pos++)\r
{\r
ecmd[pos] = crypto1_byte(pcs, 0x00, 0) ^ dcmd[pos];\r
- par = (par >> 1) | ( ((filter(pcs->odd) ^ oddparity(dcmd[pos])) & 0x01) * 0x08 );\r
+ par[0] |= (((filter(pcs->odd) ^ oddparity(dcmd[pos])) & 0x01) << (7-pos));\r
} \r
\r
ReaderTransmitPar(ecmd, sizeof(ecmd), par, timing);\r
ReaderTransmit(dcmd, sizeof(dcmd), timing);\r
}\r
\r
- int len = ReaderReceivePar(answer, &par);\r
+ int len = ReaderReceive(answer, par);\r
\r
- if (parptr) *parptr = par;\r
+ if (answer_parity) *answer_parity = par[0];\r
\r
if (crypted == CRYPT_ALL) {\r
if (len == 1) {\r
}\r
\r
// mifare commands\r
-int mifare_classic_auth(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint64_t isNested) \r
+int mifare_classic_auth(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested) \r
{\r
return mifare_classic_authex(pcs, uid, blockNo, keyType, ui64Key, isNested, NULL, NULL);\r
}\r
\r
-int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint64_t isNested, uint32_t * ntptr, uint32_t *timing) \r
+int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested, uint32_t * ntptr, uint32_t *timing) \r
{\r
// variables\r
int len; \r
uint32_t pos;\r
uint8_t tmp4[4];\r
- byte_t par = 0;\r
- byte_t ar[4];\r
+ uint8_t par[1] = {0x00};\r
+ byte_t nr[4];\r
uint32_t nt, ntpp; // Supplied tag nonce\r
\r
uint8_t mf_nr_ar[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };\r
- uint8_t* receivedAnswer = mifare_get_bigbufptr();\r
+ uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();\r
+ uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;\r
\r
// Transmit MIFARE_CLASSIC_AUTH\r
- len = mifare_sendcmd_short(pcs, isNested, 0x60 + (keyType & 0x01), blockNo, receivedAnswer, timing);\r
- if (MF_DBGLEVEL >= 4) Dbprintf("rand nonce len: %x", len); \r
+ len = mifare_sendcmd_short(pcs, isNested, 0x60 + (keyType & 0x01), blockNo, receivedAnswer, receivedAnswerPar, timing);\r
+ if (MF_DBGLEVEL >= 4) Dbprintf("rand tag nonce len: %x", len); \r
if (len != 4) return 1;\r
\r
- ar[0] = 0x55;\r
- ar[1] = 0x41;\r
- ar[2] = 0x49;\r
- ar[3] = 0x92; \r
+ // "random" reader nonce:\r
+ nr[0] = 0x55;\r
+ nr[1] = 0x41;\r
+ nr[2] = 0x49;\r
+ nr[3] = 0x92; \r
\r
// Save the tag nonce (nt)\r
nt = bytes_to_num(receivedAnswer, 4);\r
if (ntptr)\r
*ntptr = nt;\r
\r
- par = 0;\r
// Generate (encrypted) nr+parity by loading it into the cipher (Nr)\r
+ par[0] = 0;\r
for (pos = 0; pos < 4; pos++)\r
{\r
- mf_nr_ar[pos] = crypto1_byte(pcs, ar[pos], 0) ^ ar[pos];\r
- par = (par >> 1) | ( ((filter(pcs->odd) ^ oddparity(ar[pos])) & 0x01) * 0x80 );\r
+ mf_nr_ar[pos] = crypto1_byte(pcs, nr[pos], 0) ^ nr[pos];\r
+ par[0] |= (((filter(pcs->odd) ^ oddparity(nr[pos])) & 0x01) << (7-pos));\r
} \r
\r
// Skip 32 bits in pseudo random generator\r
{\r
nt = prng_successor(nt,8);\r
mf_nr_ar[pos] = crypto1_byte(pcs,0x00,0) ^ (nt & 0xff);\r
- par = (par >> 1)| ( ((filter(pcs->odd) ^ oddparity(nt & 0xff)) & 0x01) * 0x80 );\r
+ par[0] |= (((filter(pcs->odd) ^ oddparity(nt & 0xff)) & 0x01) << (7-pos));\r
} \r
\r
// Transmit reader nonce and reader answer\r
ReaderTransmitPar(mf_nr_ar, sizeof(mf_nr_ar), par, NULL);\r
\r
- // Receive 4 bit answer\r
- len = ReaderReceive(receivedAnswer);\r
+ // Receive 4 byte tag answer\r
+ len = ReaderReceive(receivedAnswer, receivedAnswerPar);\r
if (!len)\r
{\r
if (MF_DBGLEVEL >= 1) Dbprintf("Authentication failed. Card timeout.");\r
int len; \r
uint8_t bt[2];\r
\r
- uint8_t* receivedAnswer = mifare_get_bigbufptr();\r
+ uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();\r
+ uint8_t* receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;\r
\r
// command MIFARE_CLASSIC_READBLOCK\r
- len = mifare_sendcmd_short(pcs, 1, 0x30, blockNo, receivedAnswer, NULL);\r
+ len = mifare_sendcmd_short(pcs, 1, 0x30, blockNo, receivedAnswer, receivedAnswerPar, NULL);\r
if (len == 1) {\r
if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Error: %02x", receivedAnswer[0]); \r
return 1;\r
\r
int mifare_ultra_auth1(uint32_t uid, uint8_t *blockData){\r
// variables\r
- int len;\r
+ uint16_t len;\r
\r
- uint8_t* receivedAnswer = mifare_get_bigbufptr();\r
+ uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();\r
+ uint8_t* receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;\r
\r
// command MIFARE_CLASSIC_READBLOCK\r
- len = mifare_sendcmd_short(NULL, 1, 0x1A, 0x00, receivedAnswer,NULL);\r
+ len = mifare_sendcmd_short(NULL, 1, 0x1A, 0x00, receivedAnswer,receivedAnswerPar ,NULL);\r
if (len == 1) {\r
if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Error: %02x", receivedAnswer[0]);\r
return 1;\r
receivedAnswer[5],receivedAnswer[6],receivedAnswer[7],receivedAnswer[8],receivedAnswer[9],\r
receivedAnswer[10]);\r
memcpy(blockData, receivedAnswer, 11);\r
- return 0;\r
+ return 0;\r
}\r
//else something went wrong???\r
return 1;\r
\r
int mifare_ultra_auth2(uint32_t uid, uint8_t *key, uint8_t *blockData){\r
// variables\r
- int len;\r
- \r
- uint8_t* receivedAnswer = mifare_get_bigbufptr();\r
+ uint16_t len;\r
\r
+ uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();\r
+ uint8_t* receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;\r
\r
// command MIFARE_CLASSIC_READBLOCK\r
- len = mifare_sendcmd_short_mfucauth(NULL, 1, 0xAF, key, receivedAnswer,NULL);\r
+ len = mifare_sendcmd_short_mfucauth(NULL, 1, 0xAF, key, receivedAnswer, receivedAnswerPar, NULL);\r
if (len == 1) {\r
if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Error: %02x", receivedAnswer[0]);\r
return 1;\r
int mifare_ultra_readblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData)
{
// variables
- int len;
+ uint16_t len;
uint8_t bt[2];
- uint8_t* receivedAnswer = mifare_get_bigbufptr();
+ uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();
+ uint8_t* receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;\r
+ \r
// command MIFARE_CLASSIC_READBLOCK
- len = mifare_sendcmd_short(NULL, 1, 0x30, blockNo, receivedAnswer,NULL);
+ len = mifare_sendcmd_short(NULL, 1, 0x30, blockNo, receivedAnswer, receivedAnswerPar, NULL);
if (len == 1) {
if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
return 1;
int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData)
{
// variables
- int len, i; \r
+ uint16_t len, i; \r
uint32_t pos;\r
- uint32_t par = 0;\r
+ uint8_t par[3] = {0x00};\r
byte_t res;\r
\r
uint8_t d_block[18], d_block_enc[18];\r
- uint8_t* receivedAnswer = mifare_get_bigbufptr();\r
+ uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();\r
+ uint8_t* receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;\r
\r
// command MIFARE_CLASSIC_WRITEBLOCK\r
- len = mifare_sendcmd_short(pcs, 1, 0xA0, blockNo, receivedAnswer, NULL);\r
+ len = mifare_sendcmd_short(pcs, 1, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL);\r
\r
if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK\r
if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Error: %02x", receivedAnswer[0]); \r
AppendCrc14443a(d_block, 16);\r
\r
// crypto\r
- par = 0;\r
for (pos = 0; pos < 18; pos++)\r
{\r
d_block_enc[pos] = crypto1_byte(pcs, 0x00, 0) ^ d_block[pos];\r
- par = (par >> 1) | ( ((filter(pcs->odd) ^ oddparity(d_block[pos])) & 0x01) * 0x20000 );\r
+ par[pos>>3] |= (((filter(pcs->odd) ^ oddparity(d_block[pos])) & 0x01) << (7 - (pos&0x0007)));\r
} \r
\r
ReaderTransmitPar(d_block_enc, sizeof(d_block_enc), par, NULL);\r
\r
// Receive the response\r
- len = ReaderReceive(receivedAnswer); \r
+ len = ReaderReceive(receivedAnswer, receivedAnswerPar); \r
\r
res = 0;\r
for (i = 0; i < 4; i++)\r
int mifare_ultra_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData)
{
- // variables
- int len;
- uint32_t par = 0;
-
- uint8_t d_block[18];
- uint8_t* receivedAnswer = mifare_get_bigbufptr();
-
- // command MIFARE_CLASSIC_WRITEBLOCK
- len = mifare_sendcmd_short(NULL, 1, 0xA0, blockNo, receivedAnswer,NULL);
+ // variables
+ uint16_t len;
+ uint8_t par[3] = {0}; // enough for 18 parity bits
+
+ uint8_t d_block[18];
+ uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();\r
+ uint8_t* receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
+
+ // command MIFARE_CLASSIC_WRITEBLOCK
+ len = mifare_sendcmd_short(NULL, true, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL);
- if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK
- if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Addr Error: %02x", receivedAnswer[0]);
- return 1;
- }
+ if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK
+ if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Addr Error: %02x", receivedAnswer[0]);
+ return 1;
+ }
memset(d_block,'\0',18);
memcpy(d_block, blockData, 16);
- AppendCrc14443a(d_block, 16);
+ AppendCrc14443a(d_block, 16);
ReaderTransmitPar(d_block, sizeof(d_block), par, NULL);
-
- // Receive the response
- len = ReaderReceive(receivedAnswer);
+\r
+ // Receive the response
+ len = ReaderReceive(receivedAnswer, receivedAnswerPar);
if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK
- if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Data Error: %02x %d", receivedAnswer[0],len);
- return 2;
- }
+ if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Data Error: %02x %d", receivedAnswer[0],len);
+ return 2;
+ }
- return 0;
+ return 0;
}
int mifare_ultra_special_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData)
{
- // variables
- int len;
- //uint32_t par = 0;
-
- uint8_t d_block[8];
- uint8_t* receivedAnswer = mifare_get_bigbufptr();
+ uint16_t len;
+\r
+ uint8_t d_block[8];
+ uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();\r
+ uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
- // command MIFARE_CLASSIC_WRITEBLOCK
+ // command MIFARE_CLASSIC_WRITEBLOCK
memset(d_block,'\0',8);
d_block[0]= blockNo;
memcpy(d_block+1,blockData,4);
AppendCrc14443a(d_block, 6);
//i know the data send here is correct
- len = mifare_sendcmd_short_special(NULL, 1, 0xA2, d_block, receivedAnswer,NULL);
+ len = mifare_sendcmd_short_special(NULL, 1, 0xA2, d_block, receivedAnswer, receivedAnswerPar, NULL);
- if (receivedAnswer[0] != 0x0A) { // 0x0a - ACK
- if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Send Error: %02x %d", receivedAnswer[0],len);
- return 1;
- }
- return 0;
+ if (receivedAnswer[0] != 0x0A) { // 0x0a - ACK
+ if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Send Error: %02x %d", receivedAnswer[0],len);
+ return 1;
+ }
+ return 0;
}
int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid)
{
- // variables
- int len; \r
- \r
- // Mifare HALT\r
- uint8_t* receivedAnswer = mifare_get_bigbufptr();\r
+ uint16_t len; \r
+ uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();\r
+ uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;\r
\r
- len = mifare_sendcmd_short(pcs, pcs == NULL ? 0:1, 0x50, 0x00, receivedAnswer, NULL);\r
+ len = mifare_sendcmd_short(pcs, pcs == NULL ? false:true, 0x50, 0x00, receivedAnswer, receivedAnswerPar, NULL);\r
if (len != 0) {\r
if (MF_DBGLEVEL >= 1) Dbprintf("halt error. response len: %x", len); \r
return 1;\r
int mifare_ultra_halt(uint32_t uid)
{
- // variables
- int len;
-
- // Mifare HALT
- uint8_t* receivedAnswer = mifare_get_bigbufptr();
+ uint16_t len; \r
+ uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();\r
+ uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;\r
- len = mifare_sendcmd_short(NULL, 1, 0x50, 0x00, receivedAnswer, NULL);
+ len = mifare_sendcmd_short(NULL, true, 0x50, 0x00, receivedAnswer, receivedAnswerPar, NULL);
if (len != 0) {
if (MF_DBGLEVEL >= 1) Dbprintf("halt error. response len: %x", len);
return 1;
\r
// work with emulator memory
void emlSetMem(uint8_t *data, int blockNum, int blocksCount) {
- uint8_t* emCARD = eml_get_bigbufptr_cardmem();
- \r
+ uint8_t* emCARD = get_bigbufptr_emlcardmem();\r
memcpy(emCARD + blockNum * 16, data, blocksCount * 16);\r
}\r
\r
void emlGetMem(uint8_t *data, int blockNum, int blocksCount) {\r
- uint8_t* emCARD = eml_get_bigbufptr_cardmem();\r
- \r
+ uint8_t* emCARD = get_bigbufptr_emlcardmem();\r
memcpy(data, emCARD + blockNum * 16, blocksCount * 16);\r
}\r
\r
void emlGetMemBt(uint8_t *data, int bytePtr, int byteCount) {\r
- uint8_t* emCARD = eml_get_bigbufptr_cardmem();\r
- \r
+ uint8_t* emCARD = get_bigbufptr_emlcardmem();\r
memcpy(data, emCARD + bytePtr, byteCount);\r
}\r
\r
int emlCheckValBl(int blockNum) {\r
- uint8_t* emCARD = eml_get_bigbufptr_cardmem();\r
+ uint8_t* emCARD = get_bigbufptr_emlcardmem();\r
uint8_t* data = emCARD + blockNum * 16;\r
\r
if ((data[0] != (data[4] ^ 0xff)) || (data[0] != data[8]) ||\r
}\r
\r
int emlGetValBl(uint32_t *blReg, uint8_t *blBlock, int blockNum) {\r
- uint8_t* emCARD = eml_get_bigbufptr_cardmem();\r
+ uint8_t* emCARD = get_bigbufptr_emlcardmem();\r
uint8_t* data = emCARD + blockNum * 16;\r
\r
if (emlCheckValBl(blockNum)) {\r
}\r
\r
memcpy(blReg, data, 4);\r
- *blBlock = data[12];\r
- \r
+ *blBlock = data[12]; \r
return 0;\r
}\r
\r
int emlSetValBl(uint32_t blReg, uint8_t blBlock, int blockNum) {\r
- uint8_t* emCARD = eml_get_bigbufptr_cardmem();\r
+ uint8_t* emCARD = get_bigbufptr_emlcardmem();\r
uint8_t* data = emCARD + blockNum * 16;\r
\r
memcpy(data + 0, &blReg, 4);\r
\r
uint64_t emlGetKey(int sectorNum, int keyType) {\r
uint8_t key[6];\r
- uint8_t* emCARD = eml_get_bigbufptr_cardmem();\r
+ uint8_t* emCARD = get_bigbufptr_emlcardmem();\r
\r
memcpy(key, emCARD + 16 * (FirstBlockOfSector(sectorNum) + NumBlocksPerSector(sectorNum) - 1) + keyType * 10, 6);\r
return bytes_to_num(key, 6);\r
\r
const uint8_t trailer[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x80, 0x69, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};\r
const uint8_t uid[] = {0xe6, 0x84, 0x87, 0xf3, 0x16, 0x88, 0x04, 0x00, 0x46, 0x8e, 0x45, 0x55, 0x4d, 0x70, 0x41, 0x04};\r
- uint8_t* emCARD = eml_get_bigbufptr_cardmem();\r
+ uint8_t* emCARD = get_bigbufptr_emlcardmem();\r
\r
- memset(emCARD, 0, CARD_MEMORY_LEN);\r
+ memset(emCARD, 0, CARD_MEMORY_SIZE);\r
\r
// fill sectors trailer data\r
for(b = 3; b < 256; b<127?(b+=4):(b+=16)) {\r
#define cardSTATE_TO_IDLE() cardSTATE = MFEMUL_IDLE; LED_B_OFF(); LED_C_OFF();\r
\r
//functions
+uint8_t* mifare_get_bigbufptr(void);
+int mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing);
+int mifare_sendcmd_short_special(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing);
+\r
+int mifare_sendcmd_short_mfucauth(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing);\r
+int mifare_sendcmd_shortex(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing);
-int mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t* answer, uint32_t *timing);
-int mifare_sendcmd_short_special(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t* amswer, uint8_t *timing);
-int mifare_sendcmd_short_mfucauth(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t* amswer, uint32_t *timing);\r
-int mifare_sendcmd_shortex(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t* answer, uint32_t * parptr, uint32_t *timing);
-
-int mifare_classic_auth(struct Crypto1State *pcs, uint32_t uid, \
- uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint64_t isNested);\r
-int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, \
- uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint64_t isNested, uint32_t * ntptr, uint32_t *timing);
+int mifare_classic_auth(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested);\r
+int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested, uint32_t * ntptr, uint32_t *timing);
int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData);
int mifare_ultra_auth1(uint32_t cuid, uint8_t *blockData);\r
int mifare_ultra_auth2(uint32_t cuid, uint8_t *key, uint8_t *blockData);\r
// crypto functions
void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *receivedCmd, int len);
-void mf_crypto1_encrypt(struct Crypto1State *pcs, uint8_t *data, int len, uint32_t *par);\r
+void mf_crypto1_encrypt(struct Crypto1State *pcs, uint8_t *data, uint16_t len, uint8_t *par);\r
uint8_t mf_crypto1_encrypt4bit(struct Crypto1State *pcs, uint8_t data);\r
\r
// memory management\r
-uint8_t* mifare_get_bigbufptr(void);\r
-uint8_t* eml_get_bigbufptr_sendbuf(void);\r
-uint8_t* eml_get_bigbufptr_recbuf(void);\r
+uint8_t* get_bigbufptr_recvrespbuf(void);\r
+uint8_t* get_bigbufptr_recvcmdbuf(void);\r
+uint8_t* get_bigbufptr_emlcardmem(void);\r
\r
// Mifare memory structure\r
uint8_t NumBlocksPerSector(uint8_t sectorNo);\r
return (data[2] << 16) | (data[1] << 8) | data[0];
}
-//added here for parity calulations
-uint8_t oddparity(uint8_t bt)
-{
- uint16_t v = bt;
- v ^= v >> 4;
- v &= 0xF;
- return ((0x9669 >> v) & 1);
-}
-
void LEDsoff()
{
LED_A_OFF();
void rol(uint8_t *data, const size_t len);
void lsl (uint8_t *data, size_t len);
int32_t le24toh (uint8_t data[3]);
-//added parity generation function here
-uint8_t oddparity(uint8_t bt);
void SpinDelay(int ms);
void SpinDelayUs(int us);
int n = strtol(Cmd, NULL, 0);
if (n == 0)
- n = 512;
+ n = 16000;
if (n > sizeof(got))
n = sizeof(got);
ShowWaitCycles = true;
}
- uint8_t got[TRACE_BUFFER_SIZE];
- GetFromBigBuf(got,sizeof(got),0);
+ uint8_t trace[TRACE_BUFFER_SIZE];
+ GetFromBigBuf(trace,TRACE_BUFFER_SIZE,0);
WaitForResponse(CMD_ACK,NULL);
PrintAndLog("Recorded Activity");
PrintAndLog(" Start | End | Src | Data");
PrintAndLog("-----------|-----------|-----|--------");
- int i = 0;
- uint32_t first_timestamp = 0;
+ uint16_t tracepos = 0;
+ uint16_t duration;
+ uint16_t data_len;
+ uint16_t parity_len;
+ bool isResponse;
uint32_t timestamp;
- uint32_t EndOfTransmissionTimestamp = 0;
+ uint32_t first_timestamp;
+ uint32_t EndOfTransmissionTimestamp;
for (;;) {
- if(i >= TRACE_BUFFER_SIZE) {
- break;
+
+ if( tracepos >= TRACE_BUFFER_SIZE) break;
+
+ timestamp = *((uint32_t *)(trace + tracepos));
+ if(tracepos == 0) {
+ first_timestamp = timestamp;
}
-
- bool isResponse;
- timestamp = *((uint32_t *)(got+i));
- if (timestamp & 0x80000000) {
- timestamp &= 0x7fffffff;
- isResponse = true;
+ tracepos += 4;
+ duration = *((uint16_t *)(trace + tracepos));
+ tracepos += 2;
+ data_len = *((uint16_t *)(trace + tracepos));
+ tracepos += 2;
+
+ if (data_len & 0x8000) {
+ data_len &= 0x7fff;
+ isResponse = true;
} else {
- isResponse = false;
+ isResponse = false;
}
- if(i==0) {
- first_timestamp = timestamp;
- }
-
- int parityBits = *((uint32_t *)(got+i+4));
+ parity_len = (data_len-1)/8 + 1;
- int len = got[i+8];
- if (len > 100) {
- break;
- }
- if (i + len >= TRACE_BUFFER_SIZE) {
- break;
- }
+ if (tracepos + data_len + parity_len >= TRACE_BUFFER_SIZE) { break; }
- uint8_t *frame = (got+i+9);
+ uint8_t *frame = trace + tracepos;
+ tracepos += data_len;
+ uint8_t *parityBytes = trace + tracepos;
+ tracepos += parity_len;
// Break and stick with current result if buffer was not completely full
- if (frame[0] == 0x44 && frame[1] == 0x44 && frame[2] == 0x44 && frame[3] == 0x44) break;
+ if (timestamp == 0x44444444) break;
char line[1000] = "";
int j;
- if (len) {
- for (j = 0; j < len; j++) {
- int oddparity = 0x01;
- int k;
-
- for (k=0;k<8;k++) {
- oddparity ^= (((frame[j] & 0xFF) >> k) & 0x01);
- }
+ for (j = 0; j < data_len; j++) {
+ int oddparity = 0x01;
+ int k;
- //if((parityBits >> (len - j - 1)) & 0x01) {
- if (isResponse && (oddparity != ((parityBits >> (len - j - 1)) & 0x01))) {
- sprintf(line+(j*4), "%02x! ", frame[j]);
- } else {
- sprintf(line+(j*4), "%02x ", frame[j]);
- }
+ for (k=0;k<8;k++) {
+ oddparity ^= (((frame[j] & 0xFF) >> k) & 0x01);
}
- } else {
- if (ShowWaitCycles) {
- uint32_t next_timestamp = (*((uint32_t *)(got+i+9))) & 0x7fffffff;
- sprintf(line, "fdt (Frame Delay Time): %d", (next_timestamp - timestamp));
+
+ uint8_t parityBits = parityBytes[j>>3];
+ if (isResponse && (oddparity != ((parityBits >> (7-(j&0x0007))) & 0x01))) {
+ sprintf(line+(j*4), "%02x! ", frame[j]);
+ } else {
+ sprintf(line+(j*4), "%02x ", frame[j]);
}
}
-
- char *crc;
- crc = "";
- if (len > 2) {
+
+ char crc[6] = "";
+ if (data_len > 2) {
uint8_t b1, b2;
- for (j = 0; j < (len - 1); j++) {
- // gives problems... search for the reason..
- /*if(frame[j] == 0xAA) {
- switch(frame[j+1]) {
- case 0x01:
- crc = "[1] Two drops close after each other";
- break;
- case 0x02:
- crc = "[2] Potential SOC with a drop in second half of bitperiod";
- break;
- case 0x03:
- crc = "[3] Segment Z after segment X is not possible";
- break;
- case 0x04:
- crc = "[4] Parity bit of a fully received byte was wrong";
- break;
- default:
- crc = "[?] Unknown error";
- break;
- }
- break;
- }*/
- }
-
- if (strlen(crc)==0) {
- ComputeCrc14443(CRC_14443_A, frame, len-2, &b1, &b2);
- if (b1 != frame[len-2] || b2 != frame[len-1]) {
- crc = (isResponse & (len < 6)) ? "" : " !crc";
- } else {
- crc = "";
- }
+ ComputeCrc14443(CRC_14443_A, frame, data_len-2, &b1, &b2);
+ if (b1 != frame[data_len-2] || b2 != frame[data_len-1]) {
+ sprintf(crc, (isResponse & (data_len < 6)) ? "" : " !crc");
+ } else {
+ sprintf(crc, "");
}
- } else {
- crc = ""; // SHORT
- }
-
- i += (len + 9);
-
- EndOfTransmissionTimestamp = (*((uint32_t *)(got+i))) & 0x7fffffff;
- if (!ShowWaitCycles) i += 9;
+ EndOfTransmissionTimestamp = timestamp + duration;
PrintAndLog(" %9d | %9d | %s | %s %s",
(timestamp - first_timestamp),
(EndOfTransmissionTimestamp - first_timestamp),
- (len?(isResponse ? "Tag" : "Rdr"):" "),
- line, crc);
-
+ (isResponse ? "Tag" : "Rdr"),
+ line,
+ crc);
+
+ bool next_isResponse = *((uint16_t *)(trace + tracepos + 6)) & 0x8000;
+ if (ShowWaitCycles && !isResponse && next_isResponse) {
+ uint32_t next_timestamp = *((uint32_t *)(trace + tracepos));
+ if (next_timestamp != 0x44444444) {
+ PrintAndLog(" %9d | %9d | %s | fdt (Frame Delay Time): %d",
+ (EndOfTransmissionTimestamp - first_timestamp),
+ (next_timestamp - first_timestamp),
+ " ",
+ (next_timestamp - EndOfTransmissionTimestamp));
+ }
+ }
+ }
}
return 0;
}
SendCommand(&c);
return 0;
}
-
+#define NUM_CSNS 15
int CmdHFiClassSim(const char *Cmd)
{
uint8_t simType = 0;
if(simType == 2)
{
- UsbCommand c = {CMD_SIMULATE_TAG_ICLASS, {simType,63}};
+ UsbCommand c = {CMD_SIMULATE_TAG_ICLASS, {simType,NUM_CSNS}};
UsbCommand resp = {0};
- uint8_t csns[64] = {
- 0x00,0x0B,0x0F,0xFF,0xF7,0xFF,0x12,0xE0 ,
- 0x00,0x13,0x94,0x7e,0x76,0xff,0x12,0xe0 ,
- 0x2a,0x99,0xac,0x79,0xec,0xff,0x12,0xe0 ,
- 0x17,0x12,0x01,0xfd,0xf7,0xff,0x12,0xe0 ,
- 0xcd,0x56,0x01,0x7c,0x6f,0xff,0x12,0xe0 ,
- 0x4b,0x5e,0x0b,0x72,0xef,0xff,0x12,0xe0 ,
- 0x00,0x73,0xd8,0x75,0x58,0xff,0x12,0xe0 ,
- 0x0c,0x90,0x32,0xf3,0x5d,0xff,0x12,0xe0 };
-
- memcpy(c.d.asBytes, csns, 64);
+ uint8_t csns[8*NUM_CSNS] = {
+ 0x00, 0x0B, 0x0F, 0xFF, 0xF7, 0xFF, 0x12, 0xE0,
+ 0x00, 0x04, 0x0E, 0x08, 0xF7, 0xFF, 0x12, 0xE0,
+ 0x00, 0x09, 0x0D, 0x05, 0xF7, 0xFF, 0x12, 0xE0,
+ 0x00, 0x0A, 0x0C, 0x06, 0xF7, 0xFF, 0x12, 0xE0,
+ 0x00, 0x0F, 0x0B, 0x03, 0xF7, 0xFF, 0x12, 0xE0,
+ 0x00, 0x08, 0x0A, 0x0C, 0xF7, 0xFF, 0x12, 0xE0,
+ 0x00, 0x0D, 0x09, 0x09, 0xF7, 0xFF, 0x12, 0xE0,
+ 0x00, 0x0E, 0x08, 0x0A, 0xF7, 0xFF, 0x12, 0xE0,
+ 0x00, 0x03, 0x07, 0x17, 0xF7, 0xFF, 0x12, 0xE0,
+ 0x00, 0x3C, 0x06, 0xE0, 0xF7, 0xFF, 0x12, 0xE0,
+ 0x00, 0x01, 0x05, 0x1D, 0xF7, 0xFF, 0x12, 0xE0,
+ 0x00, 0x02, 0x04, 0x1E, 0xF7, 0xFF, 0x12, 0xE0,
+ 0x00, 0x07, 0x03, 0x1B, 0xF7, 0xFF, 0x12, 0xE0,
+ 0x00, 0x00, 0x02, 0x24, 0xF7, 0xFF, 0x12, 0xE0,
+ 0x00, 0x05, 0x01, 0x21, 0xF7, 0xFF, 0x12, 0xE0 };
+
+ memcpy(c.d.asBytes, csns, 8*NUM_CSNS);
SendCommand(&c);
if (!WaitForResponseTimeout(CMD_ACK, &resp, -1)) {
}
uint8_t num_mac_responses = resp.arg[1];
- PrintAndLog("Mac responses: %d MACs obtained (should be 8)", num_mac_responses);
+ PrintAndLog("Mac responses: %d MACs obtained (should be %d)", num_mac_responses, NUM_CSNS);
- size_t datalen = 8*24;
+ size_t datalen = NUM_CSNS*24;
/*
* Now, time to dump to file. We'll use this format:
* <8-byte CSN><8-byte CC><4 byte NR><4 byte MAC>....
void* dump = malloc(datalen);
memset(dump,0,datalen);//<-- Need zeroes for the CC-field
uint8_t i = 0;
- for(i = 0 ; i < 8 ; i++)
+ for(i = 0 ; i < NUM_CSNS ; i++)
{
memcpy(dump+i*24, csns+i*8,8); //CSN
//8 zero bytes here...
uint8_t atqa[2];\r
uint8_t sak;\r
bool isTag;\r
- uint32_t parity;\r
uint8_t buf[3000];\r
uint8_t * bufPtr = buf;\r
memset(buf, 0x00, 3000);\r
printf(">\n");\r
PrintAndLog("received trace len: %d packages: %d", blockLen, pckNum);\r
num = 0;\r
- while (bufPtr - buf + 9 < blockLen) {\r
- isTag = bufPtr[3] & 0x80 ? true:false;\r
- bufPtr += 4;\r
- parity = *((uint32_t *)(bufPtr));\r
- bufPtr += 4;\r
- len = bufPtr[0];\r
- bufPtr++;\r
- if ((len == 14) && (bufPtr[0] == 0xff) && (bufPtr[1] == 0xff)) {\r
+ while (bufPtr - buf < blockLen) {\r
+ bufPtr += 6;\r
+ len = *((uint16_t *)bufPtr);\r
+\r
+ if(len & 0x8000) {\r
+ isTag = true;\r
+ len &= 0x7fff;\r
+ } else {\r
+ isTag = false;\r
+ }\r
+ bufPtr += 2;\r
+ if ((len == 14) && (bufPtr[0] == 0xff) && (bufPtr[1] == 0xff) && (bufPtr[12] == 0xff) && (bufPtr[13] == 0xff)) {\r
+ \r
memcpy(uid, bufPtr + 2, 7);\r
memcpy(atqa, bufPtr + 2 + 7, 2);\r
uid_len = (atqa[0] & 0xC0) == 0x40 ? 7 : 4;\r
if (wantLogToFile) \r
AddLogHex(logHexFileName, isTag ? "TAG: ":"RDR: ", bufPtr, len);\r
if (wantDecrypt) \r
- mfTraceDecode(bufPtr, len, parity, wantSaveToEmlFile);\r
+ mfTraceDecode(bufPtr, len, wantSaveToEmlFile);\r
}\r
bufPtr += len;\r
+ bufPtr += ((len-1)/8+1); // ignore parity\r
num++;\r
}\r
}\r
PrintAndLog("UID=%s (%x%08x%08x%08x%08x%08x%08x)", showbits, uid1, uid2, uid3, uid4, uid5, uid6, uid7);
}
- // Checking UID against next occurences
+ // Checking UID against next occurrences
for (; i + uidlen <= rawbit;) {
int failed = 0;
for (bit = 0; bit < uidlen; bit++) {
}
times += 1;
}
- PrintAndLog("Occurences: %d (expected %d)", times, (rawbit - start) / uidlen);
+ PrintAndLog("Occurrences: %d (expected %d)", times, (rawbit - start) / uidlen);
// Remodulating for tag cloning
GraphTraceLen = 32*uidlen;
int CmdLFSim(const char *Cmd)
{
- int i;
+ int i,j;
+
static int gap;
sscanf(Cmd, "%i", &gap);
/* convert to bitstream if necessary */
ChkBitstream(Cmd);
- PrintAndLog("Sending [%d bytes]", GraphTraceLen);
+ printf("Sending [%d bytes]", GraphTraceLen);
for (i = 0; i < GraphTraceLen; i += USB_CMD_DATA_SIZE) {
UsbCommand c={CMD_DOWNLOADED_SIM_SAMPLES_125K, {i, 0, 0}};
- int j;
+
for (j = 0; j < USB_CMD_DATA_SIZE; j++) {
c.d.asBytes[j] = GraphBuffer[i+j];
}
{"flexdemod", CmdFlexdemod, 1, "Demodulate samples for FlexPass"},
{"indalademod", CmdIndalaDemod, 1, "['224'] -- Demodulate samples for Indala 64 bit UID (option '224' for 224 bit)"},
- {"indalaclone", CmdIndalaClone, 1, "<UID> ['l']-- Clone Indala to T55x7 (UID in HEX)(option 'l' for 224 UID"},
+ {"indalaclone", CmdIndalaClone, 0, "<UID> ['l']-- Clone Indala to T55x7 (UID in HEX)(option 'l' for 224 UID"},
{"vchdemod", CmdVchDemod, 1, "['clone'] -- Demodulate samples for VeriChip"},
uint8_t uid[5] = {0x00};
if (cmdp == 'h' || cmdp == 'H') {
- PrintAndLog("Usage: lf em4x sim <UID>");
+ PrintAndLog("Usage: lf em4x 410xsim <UID>");
PrintAndLog("");
- PrintAndLog(" sample: lf em4x sim 0F0368568B");
+ PrintAndLog(" sample: lf em4x 410xsim 0F0368568B");
return 0;
}
AppendGraph(0, clock, parity[3]);
/* stop bit */
- AppendGraph(0, clock, 0);
+ AppendGraph(1, clock, 0);
- //CmdManchesterMod("64");
-
- /* booyah! */
- RepaintGraphWindow();
-
- CmdLFSim("");
+ CmdLFSim("240"); //240 start_gap.
return 0;
}
int CmdHIDDemodFSK(const char *Cmd)
{
- UsbCommand c={CMD_HID_DEMOD_FSK};
- SendCommand(&c);
- return 0;
+ int findone = 0;
+ if(Cmd[0]=='1') findone=1;
+ UsbCommand c = {CMD_HID_DEMOD_FSK};
+ c.arg[0]=findone;
+ SendCommand(&c);
+ return 0;
}
int CmdHIDSim(const char *Cmd)
{
{"help", CmdHelp, 1, "This help"},
{"demod", CmdHIDDemod, 1, "Demodulate HID Prox Card II (not optimal)"},
- {"fskdemod", CmdHIDDemodFSK, 1, "Realtime HID FSK demodulator"},
- {"sim", CmdHIDSim, 1, "<ID> -- HID tag simulator"},
- {"clone", CmdHIDClone, 1, "<ID> ['l'] -- Clone HID to T55x7 (tag must be in antenna)(option 'l' for 84bit ID)"},
+ {"fskdemod", CmdHIDDemodFSK, 0, "['1'] Realtime HID FSK demodulator (option '1' for one tag only)"},
+ {"sim", CmdHIDSim, 0, "<ID> -- HID tag simulator"},
+ {"clone", CmdHIDClone, 0, "<ID> ['l'] -- Clone HID to T55x7 (tag must be in antenna)(option 'l' for 84bit ID)"},
{NULL, NULL, 0, NULL}
};
int i = 0;
int prev = -1;
+ int len = strlen(Cmd);
- char filename[256];
+ char filename[FILE_PATH_SIZE] = { 0x00 };
FILE* pf = NULL;
+
+ if (len > FILE_PATH_SIZE)
+ len = FILE_PATH_SIZE;
+ memcpy(filename, Cmd, len);
+
+ if (strlen(filename) > 0) {
+ if ((pf = fopen(filename,"wb")) == NULL) {
+ PrintAndLog("Error: Could not open file [%s]",filename);
+ return 1;
+ }
+ }
for (;;) {
}
if (pf) {
- PrintAndLog("Recorded activity succesfully written to file: %s", filename);
fclose(pf);
+ PrintAndLog("Recorded activity succesfully written to file: %s", filename);
}
return 0;
char filename[FILE_PATH_SIZE] = { 0x00 };
FILE* pf;
bool tag_mem_supplied;
- int len = 0;
-
- len = strlen(Cmd);
+ int len = strlen(Cmd);
if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;
memcpy(filename, Cmd, len);
}
tag_mem_supplied = true;
if (fread(c.d.asBytes,48,1,pf) == 0) {
- PrintAndLog("Error: File reading error");
+ PrintAndLog("Error: File reading error");
return 1;
}
fclose(pf);
static command_t CommandTable[] =
{
{"help", CmdHelp, 1, "This help"},
- {"list", CmdLFHitagList, 1, "List Hitag trace history"},
+ {"list", CmdLFHitagList, 1, "<outfile> List Hitag trace history"},
{"reader", CmdLFHitagReader, 1, "Act like a Hitag Reader"},
- {"sim", CmdLFHitagSim, 1, "Simulate Hitag transponder"},
+ {"sim", CmdLFHitagSim, 1, "<infile> Simulate Hitag transponder"},
{"snoop", CmdLFHitagSnoop, 1, "Eavesdrop Hitag communication"},
- {NULL, NULL, 0, NULL}
+ {NULL, NULL, 0, NULL}
};
int CmdLFHitag(const char *Cmd)
int CmdIODemodFSK(const char *Cmd)
{
- UsbCommand c={CMD_IO_DEMOD_FSK};
- SendCommand(&c);
- return 0;
+ int findone = 0;
+ if (Cmd[0] =='1') findone = 1;
+
+ UsbCommand c={CMD_IO_DEMOD_FSK};
+ c.arg[0] = findone;
+ SendCommand(&c);
+ return 0;
}
int CmdIOProxDemod(const char *Cmd){
{
{"help", CmdHelp, 1, "This help"},
{"demod", CmdIOProxDemod, 1, "Demodulate Stream"},
- {"fskdemod", CmdIODemodFSK, 1, "Demodulate ioProx Tag"},
- {"clone", CmdIOClone, 1, "Clone ioProx Tag"},
+ {"fskdemod", CmdIODemodFSK, 0, "['1'] Realtime IO FSK demodulator (option '1' for one tag only)"},
+ {"clone", CmdIOClone, 0, "Clone ioProx Tag"},
{NULL, NULL, 0, NULL}
};
SendCommand(&c);\r
WaitForResponse(CMD_ACK, NULL);\r
\r
-// uint8_t data[LF_TRACE_BUFF_SIZE] = {0x00};\r
+ uint8_t data[LF_TRACE_BUFF_SIZE] = {0x00};\r
\r
- // GetFromBigBuf(data,LF_TRACE_BUFF_SIZE,3560); //3560 -- should be offset..\r
- // WaitForResponseTimeout(CMD_ACK,NULL, 1500);\r
-\r
- // for (int j = 0; j < LF_TRACE_BUFF_SIZE; j++) {\r
- // GraphBuffer[j] = (int)data[j];\r
- // }\r
- // GraphTraceLen = LF_TRACE_BUFF_SIZE;\r
- CmdSamples("12000");\r
+ GetFromBigBuf(data,LF_TRACE_BUFF_SIZE,3560); //3560 -- should be offset..\r
+ WaitForResponseTimeout(CMD_ACK,NULL, 1500);\r
+\r
+ for (int j = 0; j < LF_TRACE_BUFF_SIZE; j++) {\r
+ GraphBuffer[j] = (int)data[j];\r
+ }\r
+ GraphTraceLen = LF_TRACE_BUFF_SIZE;\r
ManchesterDemod(block);\r
- // RepaintGraphWindow();\r
+ RepaintGraphWindow();\r
return 0;\r
}\r
\r
return 0;\r
}\r
}\r
-\r
+ \r
for ( int i = 0; i <8; ++i){\r
memset(s,0,sizeof(s));\r
if ( hasPwd ) {\r
if (!HasGraphData()) return 0;\r
\r
uint8_t sizebyte = 32;\r
+ // the value 5 was selected during empirical studies of the decoded data. Some signal noise to skip.\r
uint8_t offset = 5;\r
uint32_t blockData;\r
uint8_t bits[LF_BITSSTREAM_LEN] = {0x00};\r
switch(UC->cmd) {
// First check if we are handling a debug message
case CMD_DEBUG_PRINT_STRING: {
- char s[USB_CMD_DATA_SIZE+1];
+ char s[USB_CMD_DATA_SIZE+1] = {0x00};
size_t len = MIN(UC->arg[0],USB_CMD_DATA_SIZE);
memcpy(s,UC->d.asBytes,len);
- s[len] = 0x00;
PrintAndLog("#db# %s ", s);
return;
} break;
{
UsbCommand c;
c.cmd = CMD_DEVICE_INFO;
-// SendCommand_(&c);
- SendCommand(&c);
+ SendCommand(&c);
UsbCommand resp;
ReceiveCommand(&resp);
c.arg[2] = 0;
}
SendCommand(&c);
-// SendCommand_(&c);
return wait_for_ack();
} else {
fprintf(stderr, "Note: Your bootloader does not understand the new START_FLASH command\n");
memset(block_buf, 0xFF, BLOCK_SIZE);
memcpy(block_buf, data, length);
- UsbCommand c;
-/*
- c.cmd = {CMD_SETUP_WRITE};
- for (int i = 0; i < 240; i += 48) {
- memcpy(c.d.asBytes, block_buf + i, 48);
- c.arg[0] = i / 4;
- SendCommand(&c);
-// SendCommand_(&c);
- if (wait_for_ack() < 0) {
- return -1;
- }
- }
-*/
+ UsbCommand c;
c.cmd = CMD_FINISH_WRITE;
c.arg[0] = address;
-// memcpy(c.d.asBytes, block_buf+240, 16);
-// SendCommand_(&c);
memcpy(c.d.asBytes, block_buf, length);
- SendCommand(&c);
+ SendCommand(&c);
return wait_for_ack();
}
// just reset the unit
int flash_stop_flashing(void) {
UsbCommand c = {CMD_HARDWARE_RESET};
-// SendCommand_(&c);
- SendCommand(&c);
- msleep(100);
- return 0;
+ SendCommand(&c);
+ msleep(100);
+ return 0;
}
int saveFile(const char *preferredName, const char *suffix, const void* data, size_t datalen)
{
- int size = sizeof(char) * (strlen(preferredName)+strlen(suffix)+5);
+ int size = sizeof(char) * (strlen(preferredName)+strlen(suffix)+10);
char * fileName = malloc(size);
memset(fileName,0,size);
/* We should have a valid filename now, e.g. dumpdata-3.bin */
/*Opening file for writing in binary mode*/
- FILE *fileHandle=fopen(fileName,"wb");
- if(!fileHandle) {
- prnlog("Failed to write to file '%s'", fileName);
+ FILE *fh=fopen(fileName,"wb");
+ if(!fh) {
+ PrintAndLog("Failed to write to file '%s'", fileName);
return 1;
}
- fwrite(data, 1, datalen, fileHandle);
- fclose(fileHandle);
- prnlog("Saved data to '%s'", fileName);
+ fwrite(data, 1, datalen, fh);
+ fclose(fh);
+ PrintAndLog("Saved data to '%s'", fileName);
free(fileName);
return 0;
{
FILE *filehandle = fopen(fileName, "rb");
if(!filehandle) {
- prnlog("Failed to read from file '%s'", fileName);
+ PrintAndLog("Failed to read from file '%s'", fileName);
return 1;
}
fread(data,datalen,1,filehandle);
\r
// "MAGIC" CARD\r
\r
-int mfCSetUID(uint8_t *uid, uint8_t *oldUID, int wantWipe) {\r
+int mfCSetUID(uint8_t *uid, uint8_t *oldUID, bool wantWipe) {\r
uint8_t block0[16];\r
memset(block0, 0, 16);\r
memcpy(block0, uid, 4); \r
return mfCSetBlock(0, block0, oldUID, wantWipe, CSETBLOCK_SINGLE_OPER);\r
}\r
\r
-int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, int wantWipe, uint8_t params) {\r
+int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, bool wantWipe, uint8_t params) {\r
uint8_t isOK = 0;\r
\r
UsbCommand c = {CMD_MIFARE_EML_CSETBLOCK, {wantWipe, params & (0xFE | (uid == NULL ? 0:1)), blockNo}};\r
\r
uint32_t uid; // serial number\r
uint32_t nt; // tag challenge\r
-uint32_t nt_par; \r
uint32_t nr_enc; // encrypted reader challenge\r
uint32_t ar_enc; // encrypted reader response\r
-uint32_t nr_ar_par; \r
uint32_t at_enc; // encrypted tag response\r
-uint32_t at_par; \r
\r
int isTraceCardEmpty(void) {\r
return ((traceCard[0] == 0) && (traceCard[1] == 0) && (traceCard[2] == 0) && (traceCard[3] == 0));\r
}\r
\r
\r
-int mfTraceDecode(uint8_t *data_src, int len, uint32_t parity, bool wantSaveToEmlFile) {\r
+int mfTraceDecode(uint8_t *data_src, int len, bool wantSaveToEmlFile) {\r
uint8_t data[64];\r
\r
if (traceState == TRACE_ERROR) return 1;\r
case TRACE_AUTH1: \r
if (len == 4) {\r
traceState = TRACE_AUTH2;\r
-\r
nt = bytes_to_num(data, 4);\r
- nt_par = parity;\r
return 0;\r
} else {\r
traceState = TRACE_ERROR;\r
\r
nr_enc = bytes_to_num(data, 4);\r
ar_enc = bytes_to_num(data + 4, 4);\r
- nr_ar_par = parity;\r
return 0;\r
} else {\r
traceState = TRACE_ERROR;\r
traceState = TRACE_IDLE;\r
\r
at_enc = bytes_to_num(data, 4);\r
- at_par = parity;\r
\r
// decode key here)\r
ks2 = ar_enc ^ prng_successor(nt, 64);\r
int mfEmlGetMem(uint8_t *data, int blockNum, int blocksCount);\r
int mfEmlSetMem(uint8_t *data, int blockNum, int blocksCount);\r
\r
-int mfCSetUID(uint8_t *uid, uint8_t *oldUID, int wantWipe);\r
-int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, int wantWipe, uint8_t params);\r
+int mfCSetUID(uint8_t *uid, uint8_t *oldUID, bool wantWipe);\r
+int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, bool wantWipe, uint8_t params);\r
int mfCGetBlock(uint8_t blockNo, uint8_t *data, uint8_t params);\r
\r
int mfTraceInit(uint8_t *tuid, uint8_t *atqa, uint8_t sak, bool wantSaveToEmlFile);\r
-int mfTraceDecode(uint8_t *data_src, int len, uint32_t parity, bool wantSaveToEmlFile);\r
+int mfTraceDecode(uint8_t *data_src, int len, bool wantSaveToEmlFile);\r
\r
int isTraceCardEmpty(void);\r
int isBlockEmpty(int blockN);\r