]> git.zerfleddert.de Git - proxmark3-svn/commitdiff
Fixed bug in HID clone short format. Added EM4xxx block read/write commands
authorcex123@gmail.com <cex123@gmail.com@ef4ab9da-24cd-11de-8aaa-f3a34680c41f>
Thu, 24 Jan 2013 13:21:37 +0000 (13:21 +0000)
committercex123@gmail.com <cex123@gmail.com@ef4ab9da-24cd-11de-8aaa-f3a34680c41f>
Thu, 24 Jan 2013 13:21:37 +0000 (13:21 +0000)
armsrc/appmain.c
armsrc/apps.h
armsrc/lfops.c
client/cmdlfem4x.c
client/cmdlfem4x.h
include/usb_cmd.h

index a284cacf6ad94b13a5be4a7290e558d51d6cdabc..1c01537b7b9c6ee3823188cd3a167b04b026bcb7 100644 (file)
@@ -670,6 +670,12 @@ void UsbPacketReceived(uint8_t *packet, int len)
                        ReadPCF7931();
                        UsbSendPacket((uint8_t*)&ack, sizeof(ack));
                        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
 
 #ifdef WITH_HITAG
index fbc74dcdedc3efa869d11d02023e670dd9be2cc4..dd409f23172388cfb1239a3e8c9e6dce3094fc13 100644 (file)
@@ -128,6 +128,8 @@ int DemodPCF7931(uint8_t **outBlocks);
 int IsBlock0PCF7931(uint8_t *Block);
 int IsBlock1PCF7931(uint8_t *Block);
 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
 void SimulateIso14443Tag(void);
index 3b7216ed35d189eac699296aba56ee33f90d2347..cde4ae543f515f9a460c646f6a65d65bf90fe2e3 100644 (file)
@@ -1119,10 +1119,10 @@ void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT)
        data1 = 0x1D000000; // load preamble
   
        for (int i=0;i<12;i++) {
-               if (hi & (1<<(12-i)))
-                       data1 |= (1<<(((12-i)*2)+1)); // 1 -> 10
+               if (hi & (1<<(11-i)))
+                       data1 |= (1<<(((11-i)*2)+1)); // 1 -> 10
                else
-                       data1 |= (1<<((12-i)*2)); // 0 -> 01
+                       data1 |= (1<<((11-i)*2)); // 0 -> 01
        }
   
        data2 = 0;
@@ -1553,3 +1553,222 @@ void ReadPCF7931() {
   
   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();
+}
+
index 537712f441dac5aeec4b068ca4ec85b51f5a67a5..92cdb90d2248b11483bdd09b87d173c87d7dde2b 100644 (file)
@@ -423,14 +423,115 @@ int CmdEM410xWrite(const char *Cmd)
   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[] =
 {
-  {"help",        CmdHelp,        1, "This help"},
-  {"em410xread",  CmdEM410xRead,  1, "[clock rate] -- Extract ID from EM410x tag"},
-  {"em410xsim",   CmdEM410xSim,   0, "<UID> -- Simulate EM410x tag"},
-  {"em410xwatch", CmdEM410xWatch, 0, "Watches for EM410x tags"},
-  {"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"},
+  {"help",         CmdHelp,         1, "This help"},
+  {"em410xread",   CmdEM410xRead,   1, "[clock rate] -- Extract ID from EM410x tag"},
+  {"em410xsim",    CmdEM410xSim,    0, "<UID> -- Simulate EM410x tag"},
+  {"em410xwatch",  CmdEM410xWatch,  0, "Watches for EM410x tags"},
+  {"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"},
+  {"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}
 };
 
index f6f9831011503a6ffcf558c8a523aadf856191bf..a209e8f92d9b3791fab4e52a3db208804429a2b6 100644 (file)
@@ -18,5 +18,9 @@ int CmdEM410xSim(const char *Cmd);
 int CmdEM410xWatch(const char *Cmd);
 int CmdEM410xWrite(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
index 0e1b22af080d959e889a317bea947a03fc4e8062..5f4f8b703fba4941785e25a14ada15433cd89137 100644 (file)
@@ -75,6 +75,8 @@ typedef struct {
 #define CMD_T55XX_WRITE_BLOCK                                             0x0215
 #define CMD_T55XX_READ_TRACE                                              0x0216
 #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 */
 
Impressum, Datenschutz