Fixed bug in HID clone short format. Added EM4xxx block read/write commands

This commit is contained in:
cex123@gmail.com 2013-01-24 13:21:37 +00:00
parent f5fca2ed62
commit d16e0478d2
6 changed files with 343 additions and 9 deletions

View file

@ -670,6 +670,12 @@ void UsbPacketReceived(uint8_t *packet, int len)
ReadPCF7931(); ReadPCF7931();
UsbSendPacket((uint8_t*)&ack, sizeof(ack)); UsbSendPacket((uint8_t*)&ack, sizeof(ack));
break; break;
case CMD_EM4X_READ_WORD:
EM4xReadWord(c->arg[1], c->arg[2],c->d.asBytes[0]);
break;
case CMD_EM4X_WRITE_WORD:
EM4xWriteWord(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes[0]);
break;
#endif #endif
#ifdef WITH_HITAG #ifdef WITH_HITAG

View file

@ -128,6 +128,8 @@ int DemodPCF7931(uint8_t **outBlocks);
int IsBlock0PCF7931(uint8_t *Block); int IsBlock0PCF7931(uint8_t *Block);
int IsBlock1PCF7931(uint8_t *Block); int IsBlock1PCF7931(uint8_t *Block);
void ReadPCF7931(); void ReadPCF7931();
void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode);
void EM4xWriteWord(uint32_t Data, uint8_t Address, uint32_t Pwd, uint8_t PwdMode);
/// iso14443.h /// iso14443.h
void SimulateIso14443Tag(void); void SimulateIso14443Tag(void);

View file

@ -1119,10 +1119,10 @@ void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT)
data1 = 0x1D000000; // load preamble data1 = 0x1D000000; // load preamble
for (int i=0;i<12;i++) { for (int i=0;i<12;i++) {
if (hi & (1<<(12-i))) if (hi & (1<<(11-i)))
data1 |= (1<<(((12-i)*2)+1)); // 1 -> 10 data1 |= (1<<(((11-i)*2)+1)); // 1 -> 10
else else
data1 |= (1<<((12-i)*2)); // 0 -> 01 data1 |= (1<<((11-i)*2)); // 0 -> 01
} }
data2 = 0; data2 = 0;
@ -1553,3 +1553,222 @@ void ReadPCF7931() {
return ; return ;
} }
//-----------------------------------
// EM4469 / EM4305 routines
//-----------------------------------
#define FWD_CMD_LOGIN 0xC //including the even parity, binary mirrored
#define FWD_CMD_WRITE 0xA
#define FWD_CMD_READ 0x9
#define FWD_CMD_DISABLE 0x5
uint8_t forwardLink_data[64]; //array of forwarded bits
uint8_t * forward_ptr; //ptr for forward message preparation
uint8_t fwd_bit_sz; //forwardlink bit counter
uint8_t * fwd_write_ptr; //forwardlink bit pointer
//====================================================================
// prepares command bits
// see EM4469 spec
//====================================================================
//--------------------------------------------------------------------
uint8_t Prepare_Cmd( uint8_t cmd ) {
//--------------------------------------------------------------------
*forward_ptr++ = 0; //start bit
*forward_ptr++ = 0; //second pause for 4050 code
*forward_ptr++ = cmd;
cmd >>= 1;
*forward_ptr++ = cmd;
cmd >>= 1;
*forward_ptr++ = cmd;
cmd >>= 1;
*forward_ptr++ = cmd;
return 6; //return number of emited bits
}
//====================================================================
// prepares address bits
// see EM4469 spec
//====================================================================
//--------------------------------------------------------------------
uint8_t Prepare_Addr( uint8_t addr ) {
//--------------------------------------------------------------------
register uint8_t line_parity;
uint8_t i;
line_parity = 0;
for(i=0;i<6;i++) {
*forward_ptr++ = addr;
line_parity ^= addr;
addr >>= 1;
}
*forward_ptr++ = (line_parity & 1);
return 7; //return number of emited bits
}
//====================================================================
// prepares data bits intreleaved with parity bits
// see EM4469 spec
//====================================================================
//--------------------------------------------------------------------
uint8_t Prepare_Data( uint16_t data_low, uint16_t data_hi) {
//--------------------------------------------------------------------
register uint8_t line_parity;
register uint8_t column_parity;
register uint8_t i, j;
register uint16_t data;
data = data_low;
column_parity = 0;
for(i=0; i<4; i++) {
line_parity = 0;
for(j=0; j<8; j++) {
line_parity ^= data;
column_parity ^= (data & 1) << j;
*forward_ptr++ = data;
data >>= 1;
}
*forward_ptr++ = line_parity;
if(i == 1)
data = data_hi;
}
for(j=0; j<8; j++) {
*forward_ptr++ = column_parity;
column_parity >>= 1;
}
*forward_ptr = 0;
return 45; //return number of emited bits
}
//====================================================================
// Forward Link send function
// Requires: forwarLink_data filled with valid bits (1 bit per byte)
// fwd_bit_count set with number of bits to be sent
//====================================================================
void SendForward(uint8_t fwd_bit_count) {
fwd_write_ptr = forwardLink_data;
fwd_bit_sz = fwd_bit_count;
LED_D_ON();
//Field on
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
// Give it a bit of time for the resonant antenna to settle.
// And for the tag to fully power up
SpinDelay(150);
// force 1st mod pulse (start gap must be longer for 4305)
fwd_bit_sz--; //prepare next bit modulation
fwd_write_ptr++;
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
SpinDelayUs(55*8); //55 cycles off (8us each)for 4305
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);//field on
SpinDelayUs(16*8); //16 cycles on (8us each)
// now start writting
while(fwd_bit_sz-- > 0) { //prepare next bit modulation
if(((*fwd_write_ptr++) & 1) == 1)
SpinDelayUs(32*8); //32 cycles at 125Khz (8us each)
else {
//These timings work for 4469/4269/4305 (with the 55*8 above)
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
SpinDelayUs(23*8); //16-4 cycles off (8us each)
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);//field on
SpinDelayUs(9*8); //16 cycles on (8us each)
}
}
}
void Login (uint32_t Password) {
uint8_t fwd_bit_count;
forward_ptr = forwardLink_data;
fwd_bit_count = Prepare_Cmd( FWD_CMD_LOGIN );
fwd_bit_count += Prepare_Data( Password&0xFFFF, Password>>16 );
SendForward(fwd_bit_count);
//Wait for command to complete
SpinDelay(20);
}
void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode) {
uint8_t fwd_bit_count;
uint8_t *dest = (uint8_t *)BigBuf;
int m=0, i=0;
//If password mode do login
if (PwdMode == 1) Login(Pwd);
forward_ptr = forwardLink_data;
fwd_bit_count = Prepare_Cmd( FWD_CMD_READ );
fwd_bit_count += Prepare_Addr( Address );
m = sizeof(BigBuf);
// Clear destination buffer before sending the command
memset(dest, 128, m);
// Connect the A/D to the peak-detected low-frequency path.
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
// Now set up the SSC to get the ADC samples that are now streaming at us.
FpgaSetupSsc();
SendForward(fwd_bit_count);
// Now do the acquisition
i = 0;
for(;;) {
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
AT91C_BASE_SSC->SSC_THR = 0x43;
}
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
i++;
if (i >= m) break;
}
}
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
LED_D_OFF();
}
void EM4xWriteWord(uint32_t Data, uint8_t Address, uint32_t Pwd, uint8_t PwdMode) {
uint8_t fwd_bit_count;
//If password mode do login
if (PwdMode == 1) Login(Pwd);
forward_ptr = forwardLink_data;
fwd_bit_count = Prepare_Cmd( FWD_CMD_WRITE );
fwd_bit_count += Prepare_Addr( Address );
fwd_bit_count += Prepare_Data( Data&0xFFFF, Data>>16 );
SendForward(fwd_bit_count);
//Wait for write to complete
SpinDelay(20);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
LED_D_OFF();
}

View file

@ -423,14 +423,115 @@ int CmdEM410xWrite(const char *Cmd)
return 0; return 0;
} }
int CmdReadWord(const char *Cmd)
{
int Word = 16; //default to invalid word
UsbCommand c;
sscanf(Cmd, "%d", &Word);
if (Word > 15) {
PrintAndLog("Word must be between 0 and 15");
return 1;
}
PrintAndLog("Reading word %d", Word);
c.cmd = CMD_EM4X_READ_WORD;
c.d.asBytes[0] = 0x0; //Normal mode
c.arg[0] = 0;
c.arg[1] = Word;
c.arg[2] = 0;
SendCommand(&c);
return 0;
}
int CmdReadWordPWD(const char *Cmd)
{
int Word = 16; //default to invalid word
int Password = 0xFFFFFFFF; //default to blank password
UsbCommand c;
sscanf(Cmd, "%d %x", &Word, &Password);
if (Word > 15) {
PrintAndLog("Word must be between 0 and 15");
return 1;
}
PrintAndLog("Reading word %d with password %08X", Word, Password);
c.cmd = CMD_EM4X_READ_WORD;
c.d.asBytes[0] = 0x1; //Password mode
c.arg[0] = 0;
c.arg[1] = Word;
c.arg[2] = Password;
SendCommand(&c);
return 0;
}
int CmdWriteWord(const char *Cmd)
{
int Word = 16; //default to invalid block
int Data = 0xFFFFFFFF; //default to blank data
UsbCommand c;
sscanf(Cmd, "%x %d", &Data, &Word);
if (Word > 15) {
PrintAndLog("Word must be between 0 and 15");
return 1;
}
PrintAndLog("Writting word %d with data %08X", Word, Data);
c.cmd = CMD_EM4X_WRITE_WORD;
c.d.asBytes[0] = 0x0; //Normal mode
c.arg[0] = Data;
c.arg[1] = Word;
c.arg[2] = 0;
SendCommand(&c);
return 0;
}
int CmdWriteWordPWD(const char *Cmd)
{
int Word = 8; //default to invalid word
int Data = 0xFFFFFFFF; //default to blank data
int Password = 0xFFFFFFFF; //default to blank password
UsbCommand c;
sscanf(Cmd, "%x %d %x", &Data, &Word, &Password);
if (Word > 15) {
PrintAndLog("Word must be between 0 and 15");
return 1;
}
PrintAndLog("Writting word %d with data %08X and password %08X", Word, Data, Password);
c.cmd = CMD_EM4X_WRITE_WORD;
c.d.asBytes[0] = 0x1; //Password mode
c.arg[0] = Data;
c.arg[1] = Word;
c.arg[2] = Password;
SendCommand(&c);
return 0;
}
static command_t CommandTable[] = static command_t CommandTable[] =
{ {
{"help", CmdHelp, 1, "This help"}, {"help", CmdHelp, 1, "This help"},
{"em410xread", CmdEM410xRead, 1, "[clock rate] -- Extract ID from EM410x tag"}, {"em410xread", CmdEM410xRead, 1, "[clock rate] -- Extract ID from EM410x tag"},
{"em410xsim", CmdEM410xSim, 0, "<UID> -- Simulate EM410x tag"}, {"em410xsim", CmdEM410xSim, 0, "<UID> -- Simulate EM410x tag"},
{"em410xwatch", CmdEM410xWatch, 0, "Watches for EM410x tags"}, {"em410xwatch", CmdEM410xWatch, 0, "Watches for EM410x tags"},
{"em410xwrite", CmdEM410xWrite, 1, "<UID> <'0' T5555> <'1' T55x7> -- Write EM410x UID to T5555(Q5) or T55x7 tag"}, {"em410xwrite", CmdEM410xWrite, 1, "<UID> <'0' T5555> <'1' T55x7> -- Write EM410x UID to T5555(Q5) or T55x7 tag"},
{"em4x50read", CmdEM4x50Read, 1, "Extract data from EM4x50 tag"}, {"em4x50read", CmdEM4x50Read, 1, "Extract data from EM4x50 tag"},
{"readword", CmdReadWord, 1, "<Word> -- Read EM4xxx word data"},
{"readwordPWD", CmdReadWordPWD, 1, "<Word> <Password> -- Read EM4xxx word data in password mode"},
{"writeword", CmdWriteWord, 1, "<Data> <Word> -- Write EM4xxx word data"},
{"writewordPWD", CmdWriteWordPWD, 1, "<Data> <Word> <Password> -- Write EM4xxx word data in password mode"},
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };

View file

@ -18,5 +18,9 @@ int CmdEM410xSim(const char *Cmd);
int CmdEM410xWatch(const char *Cmd); int CmdEM410xWatch(const char *Cmd);
int CmdEM410xWrite(const char *Cmd); int CmdEM410xWrite(const char *Cmd);
int CmdEM4x50Read(const char *Cmd); int CmdEM4x50Read(const char *Cmd);
int CmdReadWord(const char *Cmd);
int CmdReadWordPWD(const char *Cmd);
int CmdWriteWord(const char *Cmd);
int CmdWriteWordPWD(const char *Cmd);
#endif #endif

View file

@ -75,6 +75,8 @@ typedef struct {
#define CMD_T55XX_WRITE_BLOCK 0x0215 #define CMD_T55XX_WRITE_BLOCK 0x0215
#define CMD_T55XX_READ_TRACE 0x0216 #define CMD_T55XX_READ_TRACE 0x0216
#define CMD_PCF7931_READ 0x0217 #define CMD_PCF7931_READ 0x0217
#define CMD_EM4X_READ_WORD 0x0218
#define CMD_EM4X_WRITE_WORD 0x0219
/* CMD_SET_ADC_MUX: ext1 is 0 for lopkd, 1 for loraw, 2 for hipkd, 3 for hiraw */ /* CMD_SET_ADC_MUX: ext1 is 0 for lopkd, 1 for loraw, 2 for hipkd, 3 for hiraw */