Applied Holiman's fixes for iclass.c and CSNs

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.
This commit is contained in:
iceman1001 2014-12-17 20:33:21 +01:00
commit a501c82b19
33 changed files with 1140 additions and 952 deletions

View file

@ -37,7 +37,8 @@
// 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")));
@ -68,7 +69,7 @@ void ToSendStuffBit(int b)
ToSendBit++;
if(ToSendBit >= sizeof(ToSend)) {
if(ToSendMax >= sizeof(ToSend)) {
ToSendBit = 0;
DbpString("ToSendStuffBit overflowed!");
}
@ -648,18 +649,18 @@ void UsbPacketReceived(uint8_t *packet, int len)
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:
@ -672,18 +673,16 @@ void UsbPacketReceived(uint8_t *packet, int len)
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:
@ -692,10 +691,10 @@ void UsbPacketReceived(uint8_t *packet, int len)
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;

View file

@ -32,23 +32,24 @@
// 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
uint32_t BigBuf[BIG_BUFF_SIZE];
// BIG CHANGE - UNDERSTAND THIS BEFORE WE COMMIT
#define BIGBUF_SIZE 40000
uint32_t BigBuf[BIGBUF_SIZE / sizeof(uint32_t)];
#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
#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)
//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;
@ -143,8 +144,10 @@ void ReadTItag(void);
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
@ -176,8 +179,8 @@ void RAMFUNC SnoopIso14443a(uint8_t param);
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);
@ -193,7 +196,7 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *data);
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);

View file

@ -185,6 +185,7 @@ int EPA_Read_CardAccess(uint8_t *buffer, size_t max_length)
|| response_apdu[rapdu_length - 4] != 0x90
|| response_apdu[rapdu_length - 3] != 0x00)
{
Dbprintf("epa - no select cardaccess");
return -1;
}
@ -196,6 +197,7 @@ int EPA_Read_CardAccess(uint8_t *buffer, size_t max_length)
|| response_apdu[rapdu_length - 4] != 0x90
|| response_apdu[rapdu_length - 3] != 0x00)
{
Dbprintf("epa - no read cardaccess");
return -1;
}
@ -223,7 +225,6 @@ static void EPA_PACE_Collect_Nonce_Abort(uint8_t step, int func_return)
// send the USB packet
cmd_send(CMD_ACK,step,func_return,0,0,0);
//UsbSendPacket((void *)ack, sizeof(UsbCommand));
}
//-----------------------------------------------------------------------------
@ -243,7 +244,7 @@ void EPA_PACE_Collect_Nonce(UsbCommand *c)
*/
// return value of a function
int func_return;
int func_return = 0;
// // initialize ack with 0s
// memset(ack->arg, 0, 12);
@ -253,11 +254,13 @@ void EPA_PACE_Collect_Nonce(UsbCommand *c)
func_return = EPA_Setup();
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
@ -265,10 +268,13 @@ void EPA_PACE_Collect_Nonce(UsbCommand *c)
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
@ -280,6 +286,8 @@ void EPA_PACE_Collect_Nonce(UsbCommand *c)
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);
@ -301,7 +309,6 @@ void EPA_PACE_Collect_Nonce(UsbCommand *c)
// 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);
}
@ -417,27 +424,88 @@ int EPA_PACE_MSE_Set_AT(pace_version_info_t pace_version_info, uint8_t password)
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;
}

View file

@ -744,7 +744,7 @@ void SnoopHitag(uint32_t type) {
// 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();
@ -968,7 +968,7 @@ void SimulateHitagTag(bool tag_mem_supplied, byte_t* data) {
// 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();
@ -990,19 +990,19 @@ void SimulateHitagTag(bool tag_mem_supplied, byte_t* data) {
// 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
WDT_HIT();
@ -1105,9 +1105,9 @@ void SimulateHitagTag(bool tag_mem_supplied, byte_t* data) {
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) {

View file

@ -73,7 +73,6 @@ static struct {
int nOutOfCnt;
int OutOfCnt;
int syncBit;
int parityBits;
int samples;
int highCnt;
int swapper;
@ -139,11 +138,8 @@ 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;
@ -225,12 +221,6 @@ static RAMFUNC int OutOfNDecoding(int bit)
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;
}
@ -249,12 +239,6 @@ static RAMFUNC int OutOfNDecoding(int bit)
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;
@ -315,7 +299,6 @@ static RAMFUNC int OutOfNDecoding(int bit)
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;
@ -357,7 +340,6 @@ static struct {
int bitCount;
int posCount;
int syncBit;
int parityBits;
uint16_t shiftReg;
int buffer;
int buffer2;
@ -424,7 +406,6 @@ static RAMFUNC int ManchesterDecoding(int v)
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...
@ -488,9 +469,6 @@ static RAMFUNC int ManchesterDecoding(int v)
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;
@ -571,11 +549,9 @@ static RAMFUNC int ManchesterDecoding(int v)
// 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;
@ -612,12 +588,6 @@ static RAMFUNC int ManchesterDecoding(int v)
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;
}
@ -674,7 +644,7 @@ void RAMFUNC SnoopIClass(void)
// 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);
@ -774,10 +744,10 @@ void RAMFUNC SnoopIClass(void)
//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);
}
@ -798,10 +768,10 @@ void RAMFUNC SnoopIClass(void)
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);
}
@ -996,7 +966,7 @@ void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain
{
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.
@ -1006,7 +976,7 @@ void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain
// 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
}
@ -1029,8 +999,6 @@ void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain
*/
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};
@ -1081,7 +1049,7 @@ int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived, uint8_t *reader
// + 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
@ -1221,14 +1189,13 @@ int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived, uint8_t *reader
}
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");
@ -1236,7 +1203,7 @@ int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived, uint8_t *reader
}
}
memset(receivedCmd, 0x44, RECV_CMD_SIZE);
memset(receivedCmd, 0x44, MAX_FRAME_SIZE);
}
//Dbprintf("%x", cmdsRecvd);
@ -1392,7 +1359,6 @@ void ReaderTransmitIClass(uint8_t* frame, int len)
{
int wait = 0;
int samples = 0;
int par = 0;
// This is tied to other size changes
CodeIClassCommand(frame,len);
@ -1403,7 +1369,11 @@ void ReaderTransmitIClass(uint8_t* frame, int 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);
}
}
//-----------------------------------------------------------------------------
@ -1459,7 +1429,11 @@ int ReaderReceiveIClass(uint8_t* receivedAnswer)
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;
}
@ -1499,7 +1473,7 @@ void ReaderIClass(uint8_t arg0) {
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;
@ -1590,7 +1564,7 @@ void ReaderIClass_Replay(uint8_t arg0, uint8_t *MAC) {
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();
@ -1709,7 +1683,7 @@ void IClass_iso14443A_write(uint8_t arg0, uint8_t blockNo, uint8_t *data, uint8_
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);

View file

@ -401,8 +401,7 @@ void SimulateIso14443Tag(void)
// 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();

File diff suppressed because it is too large Load diff

View file

@ -15,13 +15,6 @@
#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,
@ -35,12 +28,14 @@ typedef struct {
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 {
@ -66,32 +61,33 @@ typedef struct {
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 */

View file

@ -586,7 +586,7 @@ static void BuildIdentifyRequest(void);
//-----------------------------------------------------------------------------
void AcquireRawAdcSamplesIso15693(void)
{
uint8_t *dest = mifare_get_bigbufptr();
uint8_t *dest = get_bigbufptr_recvrespbuf();
int c = 0;
int getNext = 0;
@ -668,7 +668,7 @@ void AcquireRawAdcSamplesIso15693(void)
void RecordRawAdcSamplesIso15693(void)
{
uint8_t *dest = mifare_get_bigbufptr();
uint8_t *dest = get_bigbufptr_recvrespbuf();
int c = 0;
int getNext = 0;

View file

@ -17,6 +17,12 @@
#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)
@ -57,10 +63,9 @@ void SnoopLFRawAdcSamples(int divisor, int trigger_threshold)
// 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) {
@ -74,7 +79,7 @@ void DoAcquisition125k_internal(int trigger_threshold, bool silent)
continue;
else
trigger_threshold = -1;
if (++i >= n) break;
if (++i >= FREE_BUFFER_SIZE) break;
}
}
if (!silent){
@ -91,25 +96,20 @@ void DoAcquisition125k() {
void ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1, uint8_t *command)
{
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
/* Make sure the tag is reset */
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
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.
@ -120,7 +120,7 @@ void ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1,
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();
@ -132,8 +132,7 @@ void ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1,
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
@ -455,72 +454,162 @@ void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc)
// 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) {
// 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;
}
WDT_HIT();
}
DbpString("Enter Sim4 ");
//SpinDelayUs(512);
if ( buf[i] > 0 )
AT91C_BASE_SSC->SSC_THR = 0x43;
else
AT91C_BASE_SSC->SSC_THR = 0x00;
++i;
if(i == period) {
LED_A_ON();
if (i >= len){
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
@ -529,7 +618,7 @@ void SimulateTagLowFrequencyBidir(int divisor, int t0)
}
// 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;
@ -577,9 +666,9 @@ static void fc(int c, int *n) {
// 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
@ -666,7 +755,7 @@ size_t fsk_demod(uint8_t * dest, size_t size)
}
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;
@ -680,7 +769,7 @@ size_t aggregate_bits(uint8_t *dest,size_t size, uint8_t h2l_crossing_value,uint
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;
@ -689,7 +778,11 @@ size_t aggregate_bits(uint8_t *dest,size_t size, uint8_t h2l_crossing_value,uint
if(n < maxConsequtiveBits)
{
if ( invert==0)
memset(dest+numBits, dest[idx-1] , n);
else
memset(dest+numBits, dest[idx-1]^1 , n);
numBits += n;
}
n=0;
@ -702,7 +795,7 @@ size_t aggregate_bits(uint8_t *dest,size_t size, uint8_t h2l_crossing_value,uint
// 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;
@ -716,17 +809,15 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
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
@ -769,14 +860,12 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
(unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF);
}
}
}
// reset
hi2 = hi = lo = 0;
numshifts = 0;
}else
{
} else {
idx++;
}
}
@ -801,60 +890,69 @@ uint32_t bytebits_to_byte(uint8_t* src, int numbits)
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]);
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
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();
Dbprintf("XSF(%02d)%02x:%d (%08x%08x)",version,facilitycode,number,code,code2);
// if we're only looking for one tag
if (findone){
LED_A_OFF();
return;
if (ledcontrol) LED_A_OFF();
isFinish = 1;
break;
}
}
}
WDT_HIT();
@ -994,7 +1092,7 @@ void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMod
// 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;
@ -1030,6 +1128,7 @@ void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode)
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) {
@ -1047,9 +1146,9 @@ void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode)
// 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);
@ -1808,7 +1907,7 @@ void EM4xLogin(uint32_t Password) {
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;

View file

@ -505,7 +505,7 @@ void MifareUWriteBlock_Special(uint8_t arg0, uint8_t *datain)
}
// Return 1 if the nonce is invalid else return 0
int valid_nonce(uint32_t Nt, uint32_t NtEnc, uint32_t Ks1, byte_t * parity) {
int valid_nonce(uint32_t Nt, uint32_t NtEnc, uint32_t Ks1, uint8_t * parity) {
return ((oddparity((Nt >> 24) & 0xFF) == ((parity[0]) ^ oddparity((NtEnc >> 24) & 0xFF) ^ BIT(Ks1,16))) & \
(oddparity((Nt >> 16) & 0xFF) == ((parity[1]) ^ oddparity((NtEnc >> 16) & 0xFF) ^ BIT(Ks1,8))) & \
(oddparity((Nt >> 8) & 0xFF) == ((parity[2]) ^ oddparity((NtEnc >> 8) & 0xFF) ^ BIT(Ks1,0)))) ? 1 : 0;
@ -532,7 +532,8 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
uint16_t davg;
static uint16_t dmin, dmax;
uint8_t uid[10];
uint32_t cuid, nt1, nt2, nttmp, nttest, par, ks1;
uint32_t cuid, nt1, nt2, nttmp, nttest, ks1;
uint8_t par[1];
uint32_t target_nt[2], target_ks[2];
uint8_t par_array[4];
@ -540,7 +541,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
struct Crypto1State mpcs = {0, 0};
struct Crypto1State *pcs;
pcs = &mpcs;
uint8_t* receivedAnswer = mifare_get_bigbufptr();
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();
uint32_t auth1_time, auth2_time;
static uint16_t delta_time;
@ -597,7 +598,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
continue;
};
nttmp = prng_successor(nt1, 140); //NXP Mifare is typical around 840,but for some unlicensed/compatible mifare card this can be 160
nttmp = prng_successor(nt1, 100); //NXP Mifare is typical around 840,but for some unlicensed/compatible mifare card this can be 160
for (i = 141; i < 1200; i++) {
nttmp = prng_successor(nttmp, 1);
if (nttmp == nt2) {break;}
@ -666,19 +667,18 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
// nested authentication
auth2_time = auth1_time + delta_time;
len = mifare_sendcmd_shortex(pcs, AUTH_NESTED, 0x60 + (targetKeyType & 0x01), targetBlockNo, receivedAnswer, &par, &auth2_time);
len = mifare_sendcmd_shortex(pcs, AUTH_NESTED, 0x60 + (targetKeyType & 0x01), targetBlockNo, receivedAnswer, par, &auth2_time);
if (len != 4) {
if (MF_DBGLEVEL >= 1) Dbprintf("Nested: Auth2 error len=%d", len);
continue;
};
nt2 = bytes_to_num(receivedAnswer, 4);
if (MF_DBGLEVEL >= 3) Dbprintf("Nonce#%d: Testing nt1=%08x nt2enc=%08x nt2par=%02x", i+1, nt1, nt2, par);
if (MF_DBGLEVEL >= 3) Dbprintf("Nonce#%d: Testing nt1=%08x nt2enc=%08x nt2par=%02x", i+1, nt1, nt2, par[0]);
// Parity validity check
for (j = 0; j < 4; j++) {
par_array[j] = (oddparity(receivedAnswer[j]) != ((par & 0x08) >> 3));
par = par << 1;
par_array[j] = (oddparity(receivedAnswer[j]) != ((par[0] >> (7-j)) & 0x01));
}
ncount = 0;
@ -713,10 +713,6 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
// ----------------------------- crypto1 destroy
crypto1_destroy(pcs);
// add trace trailer
memset(uid, 0x44, 4);
LogTrace(uid, 4, 0, 0, TRUE);
byte_t buf[4 + 4 * 4];
memcpy(buf, &cuid, 4);
memcpy(buf+4, &target_nt[0], 4);
@ -947,7 +943,8 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
uint32_t cuid;
memset(uid, 0x00, 10);
uint8_t* receivedAnswer = mifare_get_bigbufptr();
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
if (workFlags & 0x08) {
// clear trace
@ -983,13 +980,13 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
// reset chip
if (needWipe){
ReaderTransmitBitsPar(wupC1,7,0, NULL);
if(!ReaderReceive(receivedAnswer) || (receivedAnswer[0] != 0x0a)) {
if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
if (MF_DBGLEVEL >= 1) Dbprintf("wupC1 error");
break;
};
ReaderTransmit(wipeC, sizeof(wipeC), NULL);
if(!ReaderReceive(receivedAnswer) || (receivedAnswer[0] != 0x0a)) {
if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
if (MF_DBGLEVEL >= 1) Dbprintf("wipeC error");
break;
};
@ -1003,19 +1000,19 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
// write block
if (workFlags & 0x02) {
ReaderTransmitBitsPar(wupC1,7,0, NULL);
if(!ReaderReceive(receivedAnswer) || (receivedAnswer[0] != 0x0a)) {
if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
if (MF_DBGLEVEL >= 1) Dbprintf("wupC1 error");
break;
};
ReaderTransmit(wupC2, sizeof(wupC2), NULL);
if(!ReaderReceive(receivedAnswer) || (receivedAnswer[0] != 0x0a)) {
if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
if (MF_DBGLEVEL >= 1) Dbprintf("wupC2 error");
break;
};
}
if ((mifare_sendcmd_short(NULL, 0, 0xA0, blockNo, receivedAnswer, NULL) != 1) || (receivedAnswer[0] != 0x0a)) {
if ((mifare_sendcmd_short(NULL, 0, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 1) || (receivedAnswer[0] != 0x0a)) {
if (MF_DBGLEVEL >= 1) Dbprintf("write block send command error");
break;
};
@ -1024,7 +1021,7 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
AppendCrc14443a(d_block, 16);
ReaderTransmit(d_block, sizeof(d_block), NULL);
if ((ReaderReceive(receivedAnswer) != 1) || (receivedAnswer[0] != 0x0a)) {
if ((ReaderReceive(receivedAnswer, receivedAnswerPar) != 1) || (receivedAnswer[0] != 0x0a)) {
if (MF_DBGLEVEL >= 1) Dbprintf("write block send data error");
break;
};
@ -1072,7 +1069,8 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
uint32_t cuid = 0;
memset(data, 0x00, 18);
uint8_t* receivedAnswer = mifare_get_bigbufptr();
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
if (workFlags & 0x08) {
// clear trace
@ -1094,20 +1092,20 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
while (true) {
if (workFlags & 0x02) {
ReaderTransmitBitsPar(wupC1,7,0, NULL);
if(!ReaderReceive(receivedAnswer) || (receivedAnswer[0] != 0x0a)) {
if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
if (MF_DBGLEVEL >= 1) Dbprintf("wupC1 error");
break;
};
ReaderTransmit(wupC2, sizeof(wupC2), NULL);
if(!ReaderReceive(receivedAnswer) || (receivedAnswer[0] != 0x0a)) {
if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
if (MF_DBGLEVEL >= 1) Dbprintf("wupC2 error");
break;
};
}
// read block
if ((mifare_sendcmd_short(NULL, 0, 0x30, blockNo, receivedAnswer, NULL) != 18)) {
if ((mifare_sendcmd_short(NULL, 0, 0x30, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 18)) {
if (MF_DBGLEVEL >= 1) Dbprintf("read block send command error");
break;
};

View file

@ -2,9 +2,10 @@
#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;
@ -58,7 +59,7 @@ void MifareSendCommand(uint8_t arg0, uint8_t arg1, uint8_t *datain){
*/
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) {
@ -191,7 +192,7 @@ void MifareDES_Auth1(uint8_t mode, uint8_t algo, uint8_t keyno, uint8_t *datain
//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};
@ -309,6 +310,9 @@ int DesfireAPDU(uint8_t *cmd, size_t cmd_len, uint8_t *dataout){
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) {
@ -316,7 +320,7 @@ int DesfireAPDU(uint8_t *cmd, size_t cmd_len, uint8_t *dataout){
}
ReaderTransmit( wCmd, wrappedLen, NULL);
status = ReaderReceive(dataout);
status = ReaderReceive(resp, resp_par);
if( status == 0x00){
if (MF_DBGLEVEL >= 4) {
@ -327,12 +331,14 @@ int DesfireAPDU(uint8_t *cmd, size_t cmd_len, uint8_t *dataout){
// 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;
}

View file

@ -37,7 +37,7 @@ bool MfSniffEnd(void){
return FALSE;
}
bool RAMFUNC MfSniffLogic(const uint8_t *data, uint16_t len, uint32_t parity, uint16_t bitCnt, bool reader) {
bool RAMFUNC MfSniffLogic(const uint8_t *data, uint16_t len, uint8_t *parity, uint16_t bitCnt, bool reader) {
if (reader && (len == 1) && (bitCnt == 7)) { // reset on 7-Bit commands from reader
sniffState = SNF_INIT;
@ -114,16 +114,16 @@ bool RAMFUNC MfSniffLogic(const uint8_t *data, uint16_t len, uint32_t parity, ui
sniffBuf[11] = sniffSAK;
sniffBuf[12] = 0xFF;
sniffBuf[13] = 0xFF;
LogTrace(sniffBuf, 14, 0, parity, true);
LogTrace(sniffBuf, 14, 0, 0, NULL, TRUE);
} // intentionally no break;
case SNF_CARD_CMD:{
LogTrace(data, len, 0, parity, true);
LogTrace(data, len, 0, 0, NULL, TRUE);
sniffState = SNF_CARD_RESP;
timerData = GetTickCount();
break;
}
case SNF_CARD_RESP:{
LogTrace(data, len, 0, parity, false);
LogTrace(data, len, 0, 0, NULL, FALSE);
sniffState = SNF_CARD_CMD;
timerData = GetTickCount();
break;

View file

@ -39,7 +39,7 @@
#define SNF_UID_7 0
bool MfSniffInit(void);
bool RAMFUNC MfSniffLogic(const uint8_t * data, uint16_t len, uint32_t parity, uint16_t bitCnt, bool reader);
bool RAMFUNC MfSniffLogic(const uint8_t *data, uint16_t len, uint8_t *parity, uint16_t bitCnt, bool reader);
bool RAMFUNC MfSniffSend(uint16_t maxTimeoutMs);
bool intMfSniffSend();
bool MfSniffEnd(void);

View file

@ -22,17 +22,14 @@
int MF_DBGLEVEL = MF_DBG_ALL;
// memory management
uint8_t* mifare_get_bigbufptr(void) {
return (((uint8_t *)BigBuf) + MIFARE_BUFF_OFFSET); // was 3560 - tied to other size changes
uint8_t* get_bigbufptr_recvrespbuf(void) {
return (((uint8_t *)BigBuf) + RECV_RESP_OFFSET);
}
uint8_t* eml_get_bigbufptr_sendbuf(void) {
uint8_t* get_bigbufptr_recvcmdbuf(void) {
return (((uint8_t *)BigBuf) + RECV_CMD_OFFSET);
}
uint8_t* eml_get_bigbufptr_recbuf(void) {
return (((uint8_t *)BigBuf) + MIFARE_BUFF_OFFSET);
}
uint8_t* eml_get_bigbufptr_cardmem(void) {
return (((uint8_t *)BigBuf) + CARD_MEMORY);
uint8_t* get_bigbufptr_emlcardmem(void) {
return (((uint8_t *)BigBuf) + CARD_MEMORY_OFFSET);
}
// crypto1 helpers
@ -53,15 +50,17 @@ void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *data, int len){
return;
}
void mf_crypto1_encrypt(struct Crypto1State *pcs, uint8_t *data, int len, uint32_t *par) {
void mf_crypto1_encrypt(struct Crypto1State *pcs, uint8_t *data, uint16_t len, uint8_t *par) {
uint8_t bt = 0;
int i;
uint32_t mltpl = 1 << (len - 1); // for len=18 it=0x20000
*par = 0;
par[0] = 0;
for (i = 0; i < len; i++) {
bt = data[i];
data[i] = crypto1_byte(pcs, 0x00, 0) ^ data[i];
*par = (*par >> 1) | ( ((filter(pcs->odd) ^ oddparity(bt)) & 0x01) * mltpl );
if((i&0x0007) == 0)
par[i>>3] = 0;
par[i>>3] |= (((filter(pcs->odd) ^ oddparity(bt)) & 0x01)<<(7-(i&0x0007)));
}
return;
}
@ -77,19 +76,20 @@ uint8_t mf_crypto1_encrypt4bit(struct Crypto1State *pcs, uint8_t data) {
}
// send commands
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(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing)
{
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);
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;
@ -97,7 +97,7 @@ int mifare_sendcmd_short_special(struct Crypto1State *pcs, uint8_t crypted, uint
return len;
}
int mifare_sendcmd_short_mfucauth(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t* data, uint8_t* answer, uint32_t *timing)
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)
{
uint8_t dcmd[19];
int len;
@ -106,10 +106,10 @@ int mifare_sendcmd_short_mfucauth(struct Crypto1State *pcs, uint8_t crypted, uin
AppendCrc14443a(dcmd, 17);
ReaderTransmit(dcmd, sizeof(dcmd), timing);
len = ReaderReceive(answer);
len = ReaderReceive(answer, answer_parity);
if(!len) {
if (MF_DBGLEVEL >= 1) Dbprintf("Authentication failed. Card timeout.");
len = ReaderReceive(answer);
len = ReaderReceive(answer,answer_parity);
}
if(len==1) {
if (MF_DBGLEVEL >= 1) Dbprintf("NAK - Authentication failed.");
@ -118,11 +118,11 @@ int mifare_sendcmd_short_mfucauth(struct Crypto1State *pcs, uint8_t crypted, uin
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;
uint16_t pos, res;
uint8_t par[1]; // 1 Byte parity is enough here
dcmd[0] = cmd;
dcmd[1] = data;
AppendCrc14443a(dcmd, 2);
@ -130,11 +130,11 @@ int mifare_sendcmd_shortex(struct Crypto1State *pcs, uint8_t crypted, uint8_t cm
memcpy(ecmd, dcmd, sizeof(dcmd));
if (crypted) {
par = 0;
par[0] = 0;
for (pos = 0; pos < 4; pos++)
{
ecmd[pos] = crypto1_byte(pcs, 0x00, 0) ^ dcmd[pos];
par = (par >> 1) | ( ((filter(pcs->odd) ^ oddparity(dcmd[pos])) & 0x01) * 0x08 );
par[0] |= (((filter(pcs->odd) ^ oddparity(dcmd[pos])) & 0x01) << (7-pos));
}
ReaderTransmitPar(ecmd, sizeof(ecmd), par, timing);
@ -143,9 +143,9 @@ int mifare_sendcmd_shortex(struct Crypto1State *pcs, uint8_t crypted, uint8_t cm
ReaderTransmit(dcmd, sizeof(dcmd), timing);
}
int len = ReaderReceivePar(answer, &par);
int len = ReaderReceive(answer, par);
if (parptr) *parptr = par;
if (answer_parity) *answer_parity = par[0];
if (crypted == CRYPT_ALL) {
if (len == 1) {
@ -167,33 +167,35 @@ int mifare_sendcmd_shortex(struct Crypto1State *pcs, uint8_t crypted, uint8_t cm
}
// mifare commands
int mifare_classic_auth(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint64_t isNested)
int mifare_classic_auth(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested)
{
return mifare_classic_authex(pcs, uid, blockNo, keyType, ui64Key, isNested, NULL, NULL);
}
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_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)
{
// variables
int len;
uint32_t pos;
uint8_t tmp4[4];
byte_t par = 0;
byte_t ar[4];
uint8_t par[1] = {0x00};
byte_t nr[4];
uint32_t nt, ntpp; // Supplied tag nonce
uint8_t mf_nr_ar[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
uint8_t* receivedAnswer = mifare_get_bigbufptr();
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
// Transmit MIFARE_CLASSIC_AUTH
len = mifare_sendcmd_short(pcs, isNested, 0x60 + (keyType & 0x01), blockNo, receivedAnswer, timing);
if (MF_DBGLEVEL >= 4) Dbprintf("rand nonce len: %x", len);
len = mifare_sendcmd_short(pcs, isNested, 0x60 + (keyType & 0x01), blockNo, receivedAnswer, receivedAnswerPar, timing);
if (MF_DBGLEVEL >= 4) Dbprintf("rand tag nonce len: %x", len);
if (len != 4) return 1;
ar[0] = 0x55;
ar[1] = 0x41;
ar[2] = 0x49;
ar[3] = 0x92;
// "random" reader nonce:
nr[0] = 0x55;
nr[1] = 0x41;
nr[2] = 0x49;
nr[3] = 0x92;
// Save the tag nonce (nt)
nt = bytes_to_num(receivedAnswer, 4);
@ -221,12 +223,12 @@ int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockN
if (ntptr)
*ntptr = nt;
par = 0;
// Generate (encrypted) nr+parity by loading it into the cipher (Nr)
par[0] = 0;
for (pos = 0; pos < 4; pos++)
{
mf_nr_ar[pos] = crypto1_byte(pcs, ar[pos], 0) ^ ar[pos];
par = (par >> 1) | ( ((filter(pcs->odd) ^ oddparity(ar[pos])) & 0x01) * 0x80 );
mf_nr_ar[pos] = crypto1_byte(pcs, nr[pos], 0) ^ nr[pos];
par[0] |= (((filter(pcs->odd) ^ oddparity(nr[pos])) & 0x01) << (7-pos));
}
// Skip 32 bits in pseudo random generator
@ -237,14 +239,14 @@ int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockN
{
nt = prng_successor(nt,8);
mf_nr_ar[pos] = crypto1_byte(pcs,0x00,0) ^ (nt & 0xff);
par = (par >> 1)| ( ((filter(pcs->odd) ^ oddparity(nt & 0xff)) & 0x01) * 0x80 );
par[0] |= (((filter(pcs->odd) ^ oddparity(nt & 0xff)) & 0x01) << (7-pos));
}
// Transmit reader nonce and reader answer
ReaderTransmitPar(mf_nr_ar, sizeof(mf_nr_ar), par, NULL);
// Receive 4 bit answer
len = ReaderReceive(receivedAnswer);
// Receive 4 byte tag answer
len = ReaderReceive(receivedAnswer, receivedAnswerPar);
if (!len)
{
if (MF_DBGLEVEL >= 1) Dbprintf("Authentication failed. Card timeout.");
@ -268,10 +270,11 @@ int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blo
int len;
uint8_t bt[2];
uint8_t* receivedAnswer = mifare_get_bigbufptr();
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();
uint8_t* receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
// command MIFARE_CLASSIC_READBLOCK
len = mifare_sendcmd_short(pcs, 1, 0x30, blockNo, receivedAnswer, NULL);
len = mifare_sendcmd_short(pcs, 1, 0x30, blockNo, receivedAnswer, receivedAnswerPar, NULL);
if (len == 1) {
if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
return 1;
@ -294,12 +297,13 @@ int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blo
int mifare_ultra_auth1(uint32_t uid, uint8_t *blockData){
// variables
int len;
uint16_t len;
uint8_t* receivedAnswer = mifare_get_bigbufptr();
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();
uint8_t* receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
// command MIFARE_CLASSIC_READBLOCK
len = mifare_sendcmd_short(NULL, 1, 0x1A, 0x00, receivedAnswer,NULL);
len = mifare_sendcmd_short(NULL, 1, 0x1A, 0x00, receivedAnswer,receivedAnswerPar ,NULL);
if (len == 1) {
if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
return 1;
@ -318,13 +322,13 @@ int mifare_ultra_auth1(uint32_t uid, uint8_t *blockData){
int mifare_ultra_auth2(uint32_t uid, uint8_t *key, uint8_t *blockData){
// variables
int len;
uint8_t* receivedAnswer = mifare_get_bigbufptr();
uint16_t len;
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();
uint8_t* receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
// command MIFARE_CLASSIC_READBLOCK
len = mifare_sendcmd_short_mfucauth(NULL, 1, 0xAF, key, receivedAnswer,NULL);
len = mifare_sendcmd_short_mfucauth(NULL, 1, 0xAF, key, receivedAnswer, receivedAnswerPar, NULL);
if (len == 1) {
if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
return 1;
@ -344,13 +348,15 @@ int mifare_ultra_auth2(uint32_t uid, uint8_t *key, uint8_t *blockData){
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;
// 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;
@ -375,16 +381,17 @@ int mifare_ultra_readblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData)
int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData)
{
// variables
int len, i;
uint16_t len, i;
uint32_t pos;
uint32_t par = 0;
uint8_t par[3] = {0x00};
byte_t res;
uint8_t d_block[18], d_block_enc[18];
uint8_t* receivedAnswer = mifare_get_bigbufptr();
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();
uint8_t* receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
// command MIFARE_CLASSIC_WRITEBLOCK
len = mifare_sendcmd_short(pcs, 1, 0xA0, blockNo, receivedAnswer, NULL);
len = mifare_sendcmd_short(pcs, 1, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL);
if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK
if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
@ -395,17 +402,16 @@ int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t bl
AppendCrc14443a(d_block, 16);
// crypto
par = 0;
for (pos = 0; pos < 18; pos++)
{
d_block_enc[pos] = crypto1_byte(pcs, 0x00, 0) ^ d_block[pos];
par = (par >> 1) | ( ((filter(pcs->odd) ^ oddparity(d_block[pos])) & 0x01) * 0x20000 );
par[pos>>3] |= (((filter(pcs->odd) ^ oddparity(d_block[pos])) & 0x01) << (7 - (pos&0x0007)));
}
ReaderTransmitPar(d_block_enc, sizeof(d_block_enc), par, NULL);
// Receive the response
len = ReaderReceive(receivedAnswer);
len = ReaderReceive(receivedAnswer, receivedAnswerPar);
res = 0;
for (i = 0; i < 4; i++)
@ -422,14 +428,15 @@ int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t bl
int mifare_ultra_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData)
{
// variables
int len;
uint32_t par = 0;
uint16_t len;
uint8_t par[3] = {0}; // enough for 18 parity bits
uint8_t d_block[18];
uint8_t* receivedAnswer = mifare_get_bigbufptr();
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();
uint8_t* receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
// command MIFARE_CLASSIC_WRITEBLOCK
len = mifare_sendcmd_short(NULL, 1, 0xA0, blockNo, receivedAnswer,NULL);
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]);
@ -443,7 +450,7 @@ int mifare_ultra_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData)
ReaderTransmitPar(d_block, sizeof(d_block), par, NULL);
// Receive the response
len = ReaderReceive(receivedAnswer);
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);
@ -455,12 +462,11 @@ int mifare_ultra_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData)
int mifare_ultra_special_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData)
{
// variables
int len;
//uint32_t par = 0;
uint16_t len;
uint8_t d_block[8];
uint8_t* receivedAnswer = mifare_get_bigbufptr();
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
// command MIFARE_CLASSIC_WRITEBLOCK
memset(d_block,'\0',8);
@ -469,7 +475,7 @@ int mifare_ultra_special_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *bloc
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);
@ -480,13 +486,11 @@ int mifare_ultra_special_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *bloc
int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid)
{
// variables
int len;
uint16_t len;
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
// Mifare HALT
uint8_t* receivedAnswer = mifare_get_bigbufptr();
len = mifare_sendcmd_short(pcs, pcs == NULL ? 0:1, 0x50, 0x00, receivedAnswer, NULL);
len = mifare_sendcmd_short(pcs, pcs == NULL ? false:true, 0x50, 0x00, receivedAnswer, receivedAnswerPar, NULL);
if (len != 0) {
if (MF_DBGLEVEL >= 1) Dbprintf("halt error. response len: %x", len);
return 1;
@ -497,13 +501,11 @@ int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid)
int mifare_ultra_halt(uint32_t uid)
{
// variables
int len;
uint16_t len;
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
// Mifare HALT
uint8_t* receivedAnswer = mifare_get_bigbufptr();
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;
@ -535,25 +537,22 @@ uint8_t FirstBlockOfSector(uint8_t sectorNo)
// work with emulator memory
void emlSetMem(uint8_t *data, int blockNum, int blocksCount) {
uint8_t* emCARD = eml_get_bigbufptr_cardmem();
uint8_t* emCARD = get_bigbufptr_emlcardmem();
memcpy(emCARD + blockNum * 16, data, blocksCount * 16);
}
void emlGetMem(uint8_t *data, int blockNum, int blocksCount) {
uint8_t* emCARD = eml_get_bigbufptr_cardmem();
uint8_t* emCARD = get_bigbufptr_emlcardmem();
memcpy(data, emCARD + blockNum * 16, blocksCount * 16);
}
void emlGetMemBt(uint8_t *data, int bytePtr, int byteCount) {
uint8_t* emCARD = eml_get_bigbufptr_cardmem();
uint8_t* emCARD = get_bigbufptr_emlcardmem();
memcpy(data, emCARD + bytePtr, byteCount);
}
int emlCheckValBl(int blockNum) {
uint8_t* emCARD = eml_get_bigbufptr_cardmem();
uint8_t* emCARD = get_bigbufptr_emlcardmem();
uint8_t* data = emCARD + blockNum * 16;
if ((data[0] != (data[4] ^ 0xff)) || (data[0] != data[8]) ||
@ -568,7 +567,7 @@ int emlCheckValBl(int blockNum) {
}
int emlGetValBl(uint32_t *blReg, uint8_t *blBlock, int blockNum) {
uint8_t* emCARD = eml_get_bigbufptr_cardmem();
uint8_t* emCARD = get_bigbufptr_emlcardmem();
uint8_t* data = emCARD + blockNum * 16;
if (emlCheckValBl(blockNum)) {
@ -577,12 +576,11 @@ int emlGetValBl(uint32_t *blReg, uint8_t *blBlock, int blockNum) {
memcpy(blReg, data, 4);
*blBlock = data[12];
return 0;
}
int emlSetValBl(uint32_t blReg, uint8_t blBlock, int blockNum) {
uint8_t* emCARD = eml_get_bigbufptr_cardmem();
uint8_t* emCARD = get_bigbufptr_emlcardmem();
uint8_t* data = emCARD + blockNum * 16;
memcpy(data + 0, &blReg, 4);
@ -600,7 +598,7 @@ int emlSetValBl(uint32_t blReg, uint8_t blBlock, int blockNum) {
uint64_t emlGetKey(int sectorNum, int keyType) {
uint8_t key[6];
uint8_t* emCARD = eml_get_bigbufptr_cardmem();
uint8_t* emCARD = get_bigbufptr_emlcardmem();
memcpy(key, emCARD + 16 * (FirstBlockOfSector(sectorNum) + NumBlocksPerSector(sectorNum) - 1) + keyType * 10, 6);
return bytes_to_num(key, 6);
@ -611,9 +609,9 @@ void emlClearMem(void) {
const uint8_t trailer[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x80, 0x69, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
const uint8_t uid[] = {0xe6, 0x84, 0x87, 0xf3, 0x16, 0x88, 0x04, 0x00, 0x46, 0x8e, 0x45, 0x55, 0x4d, 0x70, 0x41, 0x04};
uint8_t* emCARD = eml_get_bigbufptr_cardmem();
uint8_t* emCARD = get_bigbufptr_emlcardmem();
memset(emCARD, 0, CARD_MEMORY_LEN);
memset(emCARD, 0, CARD_MEMORY_SIZE);
// fill sectors trailer data
for(b = 3; b < 256; b<127?(b+=4):(b+=16)) {

View file

@ -53,16 +53,15 @@ extern int MF_DBGLEVEL;
#define cardSTATE_TO_IDLE() cardSTATE = MFEMUL_IDLE; LED_B_OFF(); LED_C_OFF();
//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);
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);
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_short_mfucauth(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_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_classic_auth(struct Crypto1State *pcs, uint32_t uid, \
uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint64_t isNested);
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);
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);
int mifare_ultra_auth2(uint32_t cuid, uint8_t *key, uint8_t *blockData);
@ -75,13 +74,13 @@ int mifare_ultra_halt(uint32_t uid);
// 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);
void mf_crypto1_encrypt(struct Crypto1State *pcs, uint8_t *data, uint16_t len, uint8_t *par);
uint8_t mf_crypto1_encrypt4bit(struct Crypto1State *pcs, uint8_t data);
// memory management
uint8_t* mifare_get_bigbufptr(void);
uint8_t* eml_get_bigbufptr_sendbuf(void);
uint8_t* eml_get_bigbufptr_recbuf(void);
uint8_t* get_bigbufptr_recvrespbuf(void);
uint8_t* get_bigbufptr_recvcmdbuf(void);
uint8_t* get_bigbufptr_emlcardmem(void);
// Mifare memory structure
uint8_t NumBlocksPerSector(uint8_t sectorNo);

View file

@ -85,15 +85,6 @@ int32_t le24toh (uint8_t data[3])
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();

View file

@ -35,8 +35,6 @@ uint64_t bytes_to_num(uint8_t* src, size_t len);
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);

View file

@ -461,7 +461,7 @@ int CmdSamples(const char *Cmd)
int n = strtol(Cmd, NULL, 0);
if (n == 0)
n = 512;
n = 16000;
if (n > sizeof(got))
n = sizeof(got);

View file

@ -44,8 +44,8 @@ int CmdHF14AList(const char *Cmd)
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");
@ -56,49 +56,52 @@ int CmdHF14AList(const char *Cmd)
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;
}
bool isResponse;
timestamp = *((uint32_t *)(got+i));
if (timestamp & 0x80000000) {
timestamp &= 0x7fffffff;
if( tracepos >= TRACE_BUFFER_SIZE) break;
timestamp = *((uint32_t *)(trace + tracepos));
if(tracepos == 0) {
first_timestamp = timestamp;
}
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;
}
if(i==0) {
first_timestamp = timestamp;
}
parity_len = (data_len-1)/8 + 1;
int parityBits = *((uint32_t *)(got+i+4));
int len = got[i+8];
if (tracepos + data_len + parity_len >= TRACE_BUFFER_SIZE) { break; }
if (len > 100) {
break;
}
if (i + 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++) {
for (j = 0; j < data_len; j++) {
int oddparity = 0x01;
int k;
@ -106,72 +109,45 @@ int CmdHF14AList(const char *Cmd)
oddparity ^= (((frame[j] & 0xFF) >> k) & 0x01);
}
//if((parityBits >> (len - j - 1)) & 0x01) {
if (isResponse && (oddparity != ((parityBits >> (len - j - 1)) & 0x01))) {
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]);
}
}
} else {
if (ShowWaitCycles) {
uint32_t next_timestamp = (*((uint32_t *)(got+i+9))) & 0x7fffffff;
sprintf(line, "fdt (Frame Delay Time): %d", (next_timestamp - timestamp));
}
}
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";
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 {
crc = "";
}
}
} else {
crc = ""; // SHORT
sprintf(crc, "");
}
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;
}

View file

@ -302,7 +302,7 @@ int CmdHFiClassSnoop(const char *Cmd)
SendCommand(&c);
return 0;
}
#define NUM_CSNS 15
int CmdHFiClassSim(const char *Cmd)
{
uint8_t simType = 0;
@ -339,20 +339,27 @@ int CmdHFiClassSim(const char *Cmd)
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 };
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, 64);
memcpy(c.d.asBytes, csns, 8*NUM_CSNS);
SendCommand(&c);
if (!WaitForResponseTimeout(CMD_ACK, &resp, -1)) {
@ -361,9 +368,9 @@ int CmdHFiClassSim(const char *Cmd)
}
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>....
@ -377,7 +384,7 @@ int CmdHFiClassSim(const char *Cmd)
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...

View file

@ -2020,7 +2020,6 @@ int CmdHF14AMfSniff(const char *Cmd){
uint8_t atqa[2];
uint8_t sak;
bool isTag;
uint32_t parity;
uint8_t buf[3000];
uint8_t * bufPtr = buf;
memset(buf, 0x00, 3000);
@ -2087,14 +2086,19 @@ int CmdHF14AMfSniff(const char *Cmd){
printf(">\n");
PrintAndLog("received trace len: %d packages: %d", blockLen, pckNum);
num = 0;
while (bufPtr - buf + 9 < blockLen) {
isTag = bufPtr[3] & 0x80 ? true:false;
bufPtr += 4;
parity = *((uint32_t *)(bufPtr));
bufPtr += 4;
len = bufPtr[0];
bufPtr++;
if ((len == 14) && (bufPtr[0] == 0xff) && (bufPtr[1] == 0xff)) {
while (bufPtr - buf < blockLen) {
bufPtr += 6;
len = *((uint16_t *)bufPtr);
if(len & 0x8000) {
isTag = true;
len &= 0x7fff;
} else {
isTag = false;
}
bufPtr += 2;
if ((len == 14) && (bufPtr[0] == 0xff) && (bufPtr[1] == 0xff) && (bufPtr[12] == 0xff) && (bufPtr[13] == 0xff)) {
memcpy(uid, bufPtr + 2, 7);
memcpy(atqa, bufPtr + 2 + 7, 2);
uid_len = (atqa[0] & 0xC0) == 0x40 ? 7 : 4;
@ -2116,9 +2120,10 @@ int CmdHF14AMfSniff(const char *Cmd){
if (wantLogToFile)
AddLogHex(logHexFileName, isTag ? "TAG: ":"RDR: ", bufPtr, len);
if (wantDecrypt)
mfTraceDecode(bufPtr, len, parity, wantSaveToEmlFile);
mfTraceDecode(bufPtr, len, wantSaveToEmlFile);
}
bufPtr += len;
bufPtr += ((len-1)/8+1); // ignore parity
num++;
}
}

View file

@ -268,7 +268,7 @@ int CmdIndalaDemod(const char *Cmd)
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++) {
@ -282,7 +282,7 @@ int CmdIndalaDemod(const char *Cmd)
}
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;
@ -390,7 +390,8 @@ static void ChkBitstream(const char *str)
int CmdLFSim(const char *Cmd)
{
int i;
int i,j;
static int gap;
sscanf(Cmd, "%i", &gap);
@ -398,10 +399,10 @@ int CmdLFSim(const char *Cmd)
/* 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];
}
@ -569,7 +570,7 @@ static command_t CommandTable[] =
{"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"},

View file

@ -202,9 +202,9 @@ int CmdEM410xSim(const char *Cmd)
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;
}
@ -258,14 +258,9 @@ int CmdEM410xSim(const char *Cmd)
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;
}

View file

@ -39,7 +39,10 @@ int CmdHIDDemod(const char *Cmd)
int CmdHIDDemodFSK(const char *Cmd)
{
UsbCommand c={CMD_HID_DEMOD_FSK};
int findone = 0;
if(Cmd[0]=='1') findone=1;
UsbCommand c = {CMD_HID_DEMOD_FSK};
c.arg[0]=findone;
SendCommand(&c);
return 0;
}
@ -103,9 +106,9 @@ static command_t CommandTable[] =
{
{"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}
};

View file

@ -39,10 +39,22 @@ int CmdLFHitagList(const char *Cmd)
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(i >= TRACE_BUFFER_SIZE) { break; }
@ -116,8 +128,8 @@ int CmdLFHitagList(const char *Cmd)
}
if (pf) {
PrintAndLog("Recorded activity succesfully written to file: %s", filename);
fclose(pf);
PrintAndLog("Recorded activity succesfully written to file: %s", filename);
}
return 0;
@ -135,9 +147,7 @@ int CmdLFHitagSim(const char *Cmd) {
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);
@ -234,9 +244,9 @@ int CmdLFHitagReader(const char *Cmd) {
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}
};

View file

@ -16,7 +16,11 @@ static int CmdHelp(const char *Cmd);
int CmdIODemodFSK(const char *Cmd)
{
int findone = 0;
if (Cmd[0] =='1') findone = 1;
UsbCommand c={CMD_IO_DEMOD_FSK};
c.arg[0] = findone;
SendCommand(&c);
return 0;
}
@ -64,8 +68,8 @@ static command_t CommandTable[] =
{
{"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}
};

View file

@ -46,18 +46,17 @@ int CmdReadBlk(const char *Cmd)
SendCommand(&c);
WaitForResponse(CMD_ACK, NULL);
// uint8_t data[LF_TRACE_BUFF_SIZE] = {0x00};
uint8_t data[LF_TRACE_BUFF_SIZE] = {0x00};
// GetFromBigBuf(data,LF_TRACE_BUFF_SIZE,3560); //3560 -- should be offset..
// WaitForResponseTimeout(CMD_ACK,NULL, 1500);
GetFromBigBuf(data,LF_TRACE_BUFF_SIZE,3560); //3560 -- should be offset..
WaitForResponseTimeout(CMD_ACK,NULL, 1500);
// for (int j = 0; j < LF_TRACE_BUFF_SIZE; j++) {
// GraphBuffer[j] = (int)data[j];
// }
// GraphTraceLen = LF_TRACE_BUFF_SIZE;
CmdSamples("12000");
for (int j = 0; j < LF_TRACE_BUFF_SIZE; j++) {
GraphBuffer[j] = (int)data[j];
}
GraphTraceLen = LF_TRACE_BUFF_SIZE;
ManchesterDemod(block);
// RepaintGraphWindow();
RepaintGraphWindow();
return 0;
}
@ -352,6 +351,7 @@ int ManchesterDemod(int blockNum){
if (!HasGraphData()) return 0;
uint8_t sizebyte = 32;
// the value 5 was selected during empirical studies of the decoded data. Some signal noise to skip.
uint8_t offset = 5;
uint32_t blockData;
uint8_t bits[LF_BITSSTREAM_LEN] = {0x00};

View file

@ -198,10 +198,9 @@ void UsbCommandReceived(UsbCommand *UC)
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;

View file

@ -275,7 +275,6 @@ static int get_proxmark_state(uint32_t *state)
{
UsbCommand c;
c.cmd = CMD_DEVICE_INFO;
// SendCommand_(&c);
SendCommand(&c);
UsbCommand resp;
ReceiveCommand(&resp);
@ -390,7 +389,6 @@ int flash_start_flashing(int enable_bl_writes,char *serial_port_name)
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");
@ -407,22 +405,8 @@ static int write_block(uint32_t address, uint8_t *data, uint32_t length)
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;
}
}
*/
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);
return wait_for_ack();
@ -485,7 +469,6 @@ void flash_free(flash_file_t *ctx)
// just reset the unit
int flash_stop_flashing(void) {
UsbCommand c = {CMD_HARDWARE_RESET};
// SendCommand_(&c);
SendCommand(&c);
msleep(100);
return 0;

View file

@ -56,7 +56,7 @@ int fileExists(const char *filename) {
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);
@ -70,14 +70,14 @@ int saveFile(const char *preferredName, const char *suffix, const void* data, si
/* 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;
@ -87,7 +87,7 @@ int loadFile(const char *fileName, void* data, size_t datalen)
{
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);

View file

@ -231,7 +231,7 @@ int mfEmlSetMem(uint8_t *data, int blockNum, int blocksCount) {
// "MAGIC" CARD
int mfCSetUID(uint8_t *uid, uint8_t *oldUID, int wantWipe) {
int mfCSetUID(uint8_t *uid, uint8_t *oldUID, bool wantWipe) {
uint8_t block0[16];
memset(block0, 0, 16);
memcpy(block0, uid, 4);
@ -244,7 +244,7 @@ int mfCSetUID(uint8_t *uid, uint8_t *oldUID, int wantWipe) {
return mfCSetBlock(0, block0, oldUID, wantWipe, CSETBLOCK_SINGLE_OPER);
}
int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, int wantWipe, uint8_t params) {
int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, bool wantWipe, uint8_t params) {
uint8_t isOK = 0;
UsbCommand c = {CMD_MIFARE_EML_CSETBLOCK, {wantWipe, params & (0xFE | (uid == NULL ? 0:1)), blockNo}};
@ -303,12 +303,9 @@ uint32_t ks3;
uint32_t uid; // serial number
uint32_t nt; // tag challenge
uint32_t nt_par;
uint32_t nr_enc; // encrypted reader challenge
uint32_t ar_enc; // encrypted reader response
uint32_t nr_ar_par;
uint32_t at_enc; // encrypted tag response
uint32_t at_par;
int isTraceCardEmpty(void) {
return ((traceCard[0] == 0) && (traceCard[1] == 0) && (traceCard[2] == 0) && (traceCard[3] == 0));
@ -415,7 +412,7 @@ void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *data, int len, bool i
}
int mfTraceDecode(uint8_t *data_src, int len, uint32_t parity, bool wantSaveToEmlFile) {
int mfTraceDecode(uint8_t *data_src, int len, bool wantSaveToEmlFile) {
uint8_t data[64];
if (traceState == TRACE_ERROR) return 1;
@ -516,9 +513,7 @@ int mfTraceDecode(uint8_t *data_src, int len, uint32_t parity, bool wantSaveToEm
case TRACE_AUTH1:
if (len == 4) {
traceState = TRACE_AUTH2;
nt = bytes_to_num(data, 4);
nt_par = parity;
return 0;
} else {
traceState = TRACE_ERROR;
@ -532,7 +527,6 @@ int mfTraceDecode(uint8_t *data_src, int len, uint32_t parity, bool wantSaveToEm
nr_enc = bytes_to_num(data, 4);
ar_enc = bytes_to_num(data + 4, 4);
nr_ar_par = parity;
return 0;
} else {
traceState = TRACE_ERROR;
@ -545,7 +539,6 @@ int mfTraceDecode(uint8_t *data_src, int len, uint32_t parity, bool wantSaveToEm
traceState = TRACE_IDLE;
at_enc = bytes_to_num(data, 4);
at_par = parity;
// decode key here)
ks2 = ar_enc ^ prng_successor(nt, 64);

View file

@ -55,12 +55,12 @@ int mfCheckKeys (uint8_t blockNo, uint8_t keyType, uint8_t keycnt, uint8_t * key
int mfEmlGetMem(uint8_t *data, int blockNum, int blocksCount);
int mfEmlSetMem(uint8_t *data, int blockNum, int blocksCount);
int mfCSetUID(uint8_t *uid, uint8_t *oldUID, int wantWipe);
int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, int wantWipe, uint8_t params);
int mfCSetUID(uint8_t *uid, uint8_t *oldUID, bool wantWipe);
int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, bool wantWipe, uint8_t params);
int mfCGetBlock(uint8_t blockNo, uint8_t *data, uint8_t params);
int mfTraceInit(uint8_t *tuid, uint8_t *atqa, uint8_t sak, bool wantSaveToEmlFile);
int mfTraceDecode(uint8_t *data_src, int len, uint32_t parity, bool wantSaveToEmlFile);
int mfTraceDecode(uint8_t *data_src, int len, bool wantSaveToEmlFile);
int isTraceCardEmpty(void);
int isBlockEmpty(int blockN);