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
parent 02306bac2d
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
#define BIGBUF_SIZE 40000
uint32_t BigBuf[BIGBUF_SIZE / sizeof(uint32_t)];
#define TRACE_OFFSET 0
#define TRACE_SIZE 3000
#define RECV_CMD_OFFSET (TRACE_OFFSET + TRACE_SIZE)
#define MAX_FRAME_SIZE 256
#define MAX_PARITY_SIZE ((MAX_FRAME_SIZE + 1)/ 8)
#define RECV_CMD_PAR_OFFSET (RECV_CMD_OFFSET + MAX_FRAME_SIZE)
#define RECV_RESP_OFFSET (RECV_CMD_PAR_OFFSET + MAX_PARITY_SIZE)
#define RECV_RESP_PAR_OFFSET (RECV_RESP_OFFSET + MAX_FRAME_SIZE)
#define CARD_MEMORY_OFFSET (RECV_RESP_PAR_OFFSET + MAX_PARITY_SIZE)
#define CARD_MEMORY_SIZE 4096
#define DMA_BUFFER_OFFSET CARD_MEMORY_OFFSET
#define DMA_BUFFER_SIZE CARD_MEMORY_SIZE
#define FREE_BUFFER_OFFSET (CARD_MEMORY_OFFSET + CARD_MEMORY_SIZE)
#define FREE_BUFFER_SIZE (BIGBUF_SIZE - FREE_BUFFER_OFFSET - 1)
uint32_t BigBuf[BIG_BUFF_SIZE];
// BIG CHANGE - UNDERSTAND THIS BEFORE WE COMMIT
#define TRACE_OFFSET 0
#define TRACE_SIZE 4096
#define RECV_CMD_OFFSET 3032
#define RECV_CMD_SIZE 64
#define RECV_RES_OFFSET 3096
#define RECV_RES_SIZE 64
#define DMA_BUFFER_OFFSET 3160
#define DMA_BUFFER_SIZE 4096
#define FREE_BUFFER_OFFSET 7256
#define FREE_BUFFER_SIZE 2744
//extern const uint8_t OddByteParity[256];
extern const uint8_t OddByteParity[256];
extern uint8_t *trace; // = (uint8_t *) BigBuf;
extern int traceLen; // = 0;
extern int rsamples; // = 0;
@@ -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;
}
@@ -222,8 +224,7 @@ static void EPA_PACE_Collect_Nonce_Abort(uint8_t step, int func_return)
EPA_Finish();
// send the USB packet
cmd_send(CMD_ACK,step,func_return,0,0,0);
//UsbSendPacket((void *)ack, sizeof(UsbCommand));
cmd_send(CMD_ACK,step,func_return,0,0,0);
}
//-----------------------------------------------------------------------------
@@ -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);
@@ -251,13 +252,15 @@ void EPA_PACE_Collect_Nonce(UsbCommand *c)
// set up communication
func_return = EPA_Setup();
if (func_return != 0) {
if (func_return != 0) {
EPA_PACE_Collect_Nonce_Abort(1, func_return);
Dbprintf("epa: setup fucked up! %d", func_return);
return;
}
// increase the timeout (at least some cards really do need this!)
iso14a_set_timeout(0x0002FFFF);
Dbprintf("epa: Epic!");
// read the CardAccess file
// this array will hold the CardAccess file
@@ -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,8 +309,7 @@ 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);
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);
// select the card
return_code = iso14443a_select_card(uid, &card_select_info, NULL);
if (return_code != 1) {
return 1;
}
// 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;
}
iso14a_clear_trace();
iso14a_set_tracing(TRUE);
iso14a_set_timeout(10500);
return 0;
// 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
// 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];
// 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 -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();
@@ -987,21 +987,21 @@ void SimulateHitagTag(bool tag_mem_supplied, byte_t* data) {
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC1);
AT91C_BASE_PIOA->PIO_BSR = GPIO_SSC_FRAME;
// Disable timer during configuration
// Disable timer during configuration
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
// Capture mode, defaul timer source = MCK/2 (TIMER_CLOCK1), TIOA is external trigger,
// Capture mode, default timer source = MCK/2 (TIMER_CLOCK1), TIOA is external trigger,
// external trigger rising edge, load RA on rising edge of TIOA.
AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK | AT91C_TC_ETRGEDG_RISING | AT91C_TC_ABETRG | AT91C_TC_LDRA_RISING;
// Enable and reset counter
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
// Reset the received frame, frame count and timing info
memset(rx,0x00,sizeof(rx));
frame_count = 0;
response = 0;
overflow = 0;
// Enable and reset counter
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
while(!BUTTON_PRESS()) {
// Watchdog hit
@@ -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,14 +73,13 @@ static struct {
int nOutOfCnt;
int OutOfCnt;
int syncBit;
int parityBits;
int samples;
int highCnt;
int swapper;
int counter;
int bitBuffer;
int dropPosition;
uint8_t *output;
uint8_t *output;
} Uart;
static RAMFUNC int OutOfNDecoding(int bit)
@@ -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
@@ -1179,7 +1147,7 @@ int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived, uint8_t *reader
// dbprintf:ing ...
Dbprintf("CSN: %02x %02x %02x %02x %02x %02x %02x %02x",csn[0],csn[1],csn[2],csn[3],csn[4],csn[5],csn[6],csn[7]);
Dbprintf("RDR: (len=%02d): %02x %02x %02x %02x %02x %02x %02x %02x %02x",len,
receivedCmd[0], receivedCmd[1], receivedCmd[2],
receivedCmd[0], receivedCmd[1], receivedCmd[2],
receivedCmd[3], receivedCmd[4], receivedCmd[5],
receivedCmd[6], receivedCmd[7], receivedCmd[8]);
if (reader_mac_buf != NULL)
@@ -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)
{
/* Make sure the tag is reset */
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
/* Make sure the tag is reset */
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
SpinDelay(2500);
int divisor_used = 95; // 125 KHz
int divisor = 95; // 125 KHz
// see if 'h' was specified
if (command[strlen((char *) command) - 1] == 'h')
divisor_used = 88; // 134.8 KHz
divisor = 88; // 134.8 KHz
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used);
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor);
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
// Give it a bit of time for the resonant antenna to settle.
SpinDelay(50);
// And a little more time for the tag to fully power up
SpinDelay(2000);
// Now set up the SSC to get the ADC samples that are now streaming at us.
@@ -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) {
if ( buf[i] > 0 )
AT91C_BASE_SSC->SSC_THR = 0x43;
else
AT91C_BASE_SSC->SSC_THR = 0x00;
// PIO_PDSR = Pin Data Status Register
// GPIO_SSC_CLK = SSC Transmit Clock
// wait ssp_clk == high
while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) {
if(BUTTON_PRESS()) {
DbpString("Stopped at 0");
return;
}
WDT_HIT();
}
if ( buf[i] > 0 ){
OPEN_COIL();
} else {
SHORT_COIL();
}
DbpString("Enter Sim3");
// wait ssp_clk == low
while( (AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK) ) {
if(BUTTON_PRESS()) {
DbpString("stopped at 1");
return;
++i;
LED_A_ON();
if (i >= len){
i = 0;
}
WDT_HIT();
}
DbpString("Enter Sim4 ");
//SpinDelayUs(512);
++i;
if(i == period) {
i = 0;
if (gap) {
SHORT_COIL();
SpinDelay(gap);
}
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
volatile uint32_t r = AT91C_BASE_SSC->SSC_RHR;
(void)r;
LED_A_OFF();
}
}
DbpString("Stopped");
return;
DbpString("lf simulate stopped");
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
}
#define DEBUG_FRAME_CONTENTS 1
@@ -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)
{
memset(dest+numBits, dest[idx-1] , n);
if ( invert==0)
memset(dest+numBits, dest[idx-1] , n);
else
memset(dest+numBits, dest[idx-1]^1 , n);
numBits += n;
}
n=0;
@@ -702,10 +795,10 @@ 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;
uint32_t hi2=0, hi=0, lo=0;
// Configure to go in 125Khz listen mode
LFSetupFPGAForADC(0, true);
@@ -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
@@ -743,7 +834,7 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
{
// Keep going until next frame marker (or error)
// Shift in a bit. Start by shifting high registers
hi2=(hi2<<1)|(hi>>31);
hi2=(hi2<<1)|(hi>>31);
hi=(hi<<1)|(lo>>31);
//Then, shift in a 0 or one into low
if (dest[idx] && !dest[idx+1]) // 1 0
@@ -758,25 +849,23 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
// Hopefully, we read a tag and hit upon the next frame marker
if(idx + sizeof(frame_marker_mask) < size)
{
if ( memcmp(dest+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0)
{
if (hi2 != 0){
Dbprintf("TAG ID: %x%08x%08x (%d)",
(unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF);
if ( memcmp(dest+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0)
{
if (hi2 != 0){
Dbprintf("TAG ID: %x%08x%08x (%d)",
(unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF);
}
else {
Dbprintf("TAG ID: %x%08x (%d)",
(unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF);
}
}
else {
Dbprintf("TAG ID: %x%08x (%d)",
(unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF);
}
}
}
// reset
hi2 = hi = lo = 0;
numshifts = 0;
}else
{
} else {
idx++;
}
}
@@ -801,63 +890,72 @@ 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);
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
WDT_HIT();
//Index map
//0 10 20 30 40 50 60
//| | | | | | |
//01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23
//-----------------------------------------------------------------------------
//00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 ???????? 11
//
//XSF(version)facility:codeone+codetwo
//Handle the data
uint8_t mask[] = {0,0,0,0,0,0,0,0,0,1};
for( idx=0; idx < size - 64; idx++) {
if ( memcmp(dest + idx, mask, sizeof(mask)) ) continue;
Dbprintf("%d%d%d%d%d%d%d%d",dest[idx], dest[idx+1], dest[idx+2],dest[idx+3],dest[idx+4],dest[idx+5],dest[idx+6],dest[idx+7]);
Dbprintf("%d%d%d%d%d%d%d%d",dest[idx+8], dest[idx+9], dest[idx+10],dest[idx+11],dest[idx+12],dest[idx+13],dest[idx+14],dest[idx+15]);
Dbprintf("%d%d%d%d%d%d%d%d",dest[idx+16],dest[idx+17],dest[idx+18],dest[idx+19],dest[idx+20],dest[idx+21],dest[idx+22],dest[idx+23]);
Dbprintf("%d%d%d%d%d%d%d%d",dest[idx+24],dest[idx+25],dest[idx+26],dest[idx+27],dest[idx+28],dest[idx+29],dest[idx+30],dest[idx+31]);
Dbprintf("%d%d%d%d%d%d%d%d",dest[idx+32],dest[idx+33],dest[idx+34],dest[idx+35],dest[idx+36],dest[idx+37],dest[idx+38],dest[idx+39]);
Dbprintf("%d%d%d%d%d%d%d%d",dest[idx+40],dest[idx+41],dest[idx+42],dest[idx+43],dest[idx+44],dest[idx+45],dest[idx+46],dest[idx+47]);
Dbprintf("%d%d%d%d%d%d%d%d",dest[idx+48],dest[idx+49],dest[idx+50],dest[idx+51],dest[idx+52],dest[idx+53],dest[idx+54],dest[idx+55]);
Dbprintf("%d%d%d%d%d%d%d%d",dest[idx+56],dest[idx+57],dest[idx+58],dest[idx+59],dest[idx+60],dest[idx+61],dest[idx+62],dest[idx+63]);
code = bytebits_to_byte(dest+idx,32);
code2 = bytebits_to_byte(dest+idx+32,32);
for( idx=0; idx < (size - 64); idx++) {
if ( memcmp(dest + idx, mask, sizeof(mask))==0) {
//frame marker found
if(findone){ //only print binary if we are doing one
Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx], dest[idx+1], dest[idx+2],dest[idx+3],dest[idx+4],dest[idx+5],dest[idx+6],dest[idx+7],dest[idx+8]);
Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+9], dest[idx+10],dest[idx+11],dest[idx+12],dest[idx+13],dest[idx+14],dest[idx+15],dest[idx+16],dest[idx+17]);
Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+18],dest[idx+19],dest[idx+20],dest[idx+21],dest[idx+22],dest[idx+23],dest[idx+24],dest[idx+25],dest[idx+26]);
Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+27],dest[idx+28],dest[idx+29],dest[idx+30],dest[idx+31],dest[idx+32],dest[idx+33],dest[idx+34],dest[idx+35]);
Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+36],dest[idx+37],dest[idx+38],dest[idx+39],dest[idx+40],dest[idx+41],dest[idx+42],dest[idx+43],dest[idx+44]);
Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+45],dest[idx+46],dest[idx+47],dest[idx+48],dest[idx+49],dest[idx+50],dest[idx+51],dest[idx+52],dest[idx+53]);
Dbprintf("%d%d%d%d%d%d%d%d %d%d",dest[idx+54],dest[idx+55],dest[idx+56],dest[idx+57],dest[idx+58],dest[idx+59],dest[idx+60],dest[idx+61],dest[idx+62],dest[idx+63]);
}
code = bytebits_to_byte(dest+idx,32);
code2 = bytebits_to_byte(dest+idx+32,32);
short version = bytebits_to_byte(dest+idx+28,8); //14,4
char facilitycode = bytebits_to_byte(dest+idx+19,8) ;
uint16_t number = (bytebits_to_byte(dest+idx+37,8)<<8)|(bytebits_to_byte(dest+idx+46,8)); //36,9
Dbprintf("XSF(%02d)%02x:%d (%08x%08x)",version,facilitycode,number,code,code2);
short version = bytebits_to_byte(dest+idx+14,4);
char unknown = bytebits_to_byte(dest+idx+19,8) ;
uint16_t number = bytebits_to_byte(dest+idx+36,9);
Dbprintf("XSF(%02d)%02x:%d (%08x%08x)",version,unknown,number,code,code2);
if (ledcontrol) LED_D_OFF();
// if we're only looking for one tag
if (findone){
LED_A_OFF();
return;
// if we're only looking for one tag
if (findone){
if (ledcontrol) LED_A_OFF();
isFinish = 1;
break;
}
}
}
}
WDT_HIT();
WDT_HIT();
}
DbpString("Stopped");
if (ledcontrol) LED_A_OFF();
@@ -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;
@@ -561,7 +562,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
WDT_HIT();
davg = dmax = 0;
dmin = 2000;
dmin = 2000;
delta_time = 0;
for (rtr = 0; rtr < 17; rtr++) {
@@ -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
@@ -982,14 +979,14 @@ 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)) {
ReaderTransmitBitsPar(wupC1,7,0, NULL);
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;
};
@@ -1002,20 +999,20 @@ 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)) {
ReaderTransmitBitsPar(wupC1,7,0, NULL);
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);
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;
@@ -310,7 +314,7 @@ int mifare_ultra_auth1(uint32_t uid, uint8_t *blockData){
receivedAnswer[5],receivedAnswer[6],receivedAnswer[7],receivedAnswer[8],receivedAnswer[9],
receivedAnswer[10]);
memcpy(blockData, receivedAnswer, 11);
return 0;
return 0;
}
//else something went wrong???
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++)
@@ -421,72 +427,70 @@ 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;
uint8_t d_block[18];
uint8_t* receivedAnswer = mifare_get_bigbufptr();
// command MIFARE_CLASSIC_WRITEBLOCK
len = mifare_sendcmd_short(NULL, 1, 0xA0, blockNo, receivedAnswer,NULL);
// variables
uint16_t len;
uint8_t par[3] = {0}; // enough for 18 parity bits
uint8_t d_block[18];
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();
uint8_t* receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
// command MIFARE_CLASSIC_WRITEBLOCK
len = mifare_sendcmd_short(NULL, true, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL);
if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK
if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Addr Error: %02x", receivedAnswer[0]);
return 1;
}
if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK
if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Addr Error: %02x", receivedAnswer[0]);
return 1;
}
memset(d_block,'\0',18);
memcpy(d_block, blockData, 16);
AppendCrc14443a(d_block, 16);
AppendCrc14443a(d_block, 16);
ReaderTransmitPar(d_block, sizeof(d_block), par, NULL);
// Receive the response
len = ReaderReceive(receivedAnswer);
// Receive the response
len = ReaderReceive(receivedAnswer, receivedAnswerPar);
if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK
if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Data Error: %02x %d", receivedAnswer[0],len);
return 2;
}
if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Data Error: %02x %d", receivedAnswer[0],len);
return 2;
}
return 0;
return 0;
}
int mifare_ultra_special_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData)
{
// variables
int len;
//uint32_t par = 0;
uint16_t len;
uint8_t d_block[8];
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
uint8_t d_block[8];
uint8_t* receivedAnswer = mifare_get_bigbufptr();
// command MIFARE_CLASSIC_WRITEBLOCK
// command MIFARE_CLASSIC_WRITEBLOCK
memset(d_block,'\0',8);
d_block[0]= blockNo;
memcpy(d_block+1,blockData,4);
AppendCrc14443a(d_block, 6);
//i know the data send here is correct
len = mifare_sendcmd_short_special(NULL, 1, 0xA2, d_block, receivedAnswer,NULL);
len = mifare_sendcmd_short_special(NULL, 1, 0xA2, d_block, receivedAnswer, receivedAnswerPar, NULL);
if (receivedAnswer[0] != 0x0A) { // 0x0a - ACK
if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Send Error: %02x %d", receivedAnswer[0],len);
return 1;
}
return 0;
if (receivedAnswer[0] != 0x0A) { // 0x0a - ACK
if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Send Error: %02x %d", receivedAnswer[0],len);
return 1;
}
return 0;
}
int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid)
{
// variables
int len;
// Mifare HALT
uint8_t* receivedAnswer = mifare_get_bigbufptr();
uint16_t len;
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
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;
// Mifare HALT
uint8_t* receivedAnswer = mifare_get_bigbufptr();
uint16_t len;
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
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)) {
@@ -576,13 +575,12 @@ int emlGetValBl(uint32_t *blReg, uint8_t *blBlock, int blockNum) {
}
memcpy(blReg, data, 4);
*blBlock = data[12];
*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_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_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_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);