mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-19 21:03:48 -07:00
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:
parent
02306bac2d
commit
a501c82b19
33 changed files with 1140 additions and 952 deletions
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
104
armsrc/epa.c
104
armsrc/epa.c
|
@ -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;
|
||||
}
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
311
armsrc/lfops.c
311
armsrc/lfops.c
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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...
|
||||
|
|
|
@ -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++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"},
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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}
|
||||
};
|
||||
|
||||
|
|
|
@ -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}
|
||||
};
|
||||
|
|
|
@ -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}
|
||||
};
|
||||
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue