]> git.zerfleddert.de Git - proxmark3-svn/commitdiff
ADD: added identification for Mifare TNP3xxx tags.
authoriceman1001 <iceman@iuse.se>
Mon, 3 Nov 2014 12:49:19 +0000 (13:49 +0100)
committericeman1001 <iceman@iuse.se>
Mon, 3 Nov 2014 12:49:19 +0000 (13:49 +0100)
ADD: MD5-lua functionality
ADD: AES 128 decrypt lua functionality
ADD: test luc script for reading TNP3xxx tags
CHG: testing some changes for "hf 14b sim" / "lf em4x 410xsim"

15 files changed:
armsrc/iso15693.c
armsrc/lfops.c
client/cmddata.c
client/cmdhf14a.c
client/cmdlfem4x.c
client/cmdlfem4x.h
client/graph.c
client/lualibs/htmlskel.lua
client/lualibs/md5.lua [new file with mode: 0644]
client/lualibs/mf_default_keys.lua
client/lualibs/read14a.lua
client/scripting.c
client/scripts/mifare_autopwn.lua
client/scripts/tnp3.lua [new file with mode: 0644]
include/at91sam7s512.h

index 42cb0ab89c3c7bd3faee2958dfdff9b326e1c145..11a499026f39bba79606921da50904ef440a21f4 100644 (file)
@@ -463,28 +463,15 @@ static int GetIso15693AnswerFromSniff(uint8_t *receivedResponse, int maxLen, int
                        AT91C_BASE_SSC->SSC_THR = 0x43;
                }
                if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
                        AT91C_BASE_SSC->SSC_THR = 0x43;
                }
                if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
-                       int8_t b;
-                       b = (int8_t)AT91C_BASE_SSC->SSC_RHR;
+                       int8_t b = (int8_t)AT91C_BASE_SSC->SSC_RHR;
 
                        // The samples are correlations against I and Q versions of the
                        // tone that the tag AM-modulates, so every other sample is I,
                        // every other is Q. We just want power, so abs(I) + abs(Q) is
                        // close to what we want.
 
                        // The samples are correlations against I and Q versions of the
                        // tone that the tag AM-modulates, so every other sample is I,
                        // every other is Q. We just want power, so abs(I) + abs(Q) is
                        // close to what we want.
-                       if(getNext) {
-                               int8_t r;
-
-                               if(b < 0) {
-                                       r = -b;
-                               } else {
-                                       r = b;
-                               }
-                               if(prev < 0) {
-                                       r -= prev;
-                               } else {
-                                       r += prev;
-                               }
+                       if (getNext) {
 
 
-                               dest[c++] = (uint8_t)r;
+                               dest[c++] = abs(b) + abs(prev);
 
                                if(c >= 20000) {
                                        break;
 
                                if(c >= 20000) {
                                        break;
@@ -837,27 +824,27 @@ static void BuildReadBlockRequest(uint8_t *uid, uint8_t blockNumber )
 // Now the VICC>VCD responses when we are simulating a tag
  static void BuildInventoryResponse( uint8_t *uid)
 {
 // Now the VICC>VCD responses when we are simulating a tag
  static void BuildInventoryResponse( uint8_t *uid)
 {
-       uint8_t cmd[13];
+       uint8_t cmd[12];
 
        uint16_t crc;
        // one sub-carrier, inventory, 1 slot, fast rate
        // AFI is at bit 5 (1<<4) when doing an INVENTORY
 
        uint16_t crc;
        // one sub-carrier, inventory, 1 slot, fast rate
        // AFI is at bit 5 (1<<4) when doing an INVENTORY
-       cmd[0] = 0x0d;   // COM LEN? Data 8 + 4 //(1 << 2) | (1 << 5) | (1 << 1);
-       cmd[1] = 0; // com_Adr
-       cmd[2] = 0; // status   00 = success
+    //(1 << 2) | (1 << 5) | (1 << 1);
+       cmd[0] = 0; // 
+       cmd[1] = 0; // DSFID (data storage format identifier).  0x00 = not supported
        // 64-bit UID
        // 64-bit UID
-       cmd[3] = uid[7]; //0x32;
-       cmd[4] = uid[6]; //0x4b;
-       cmd[5] = uid[5]; //0x03;
-       cmd[6] = uid[4]; //0x01;
-       cmd[7] = uid[3]; //0x00;
-       cmd[8] = uid[2]; //0x10;
-       cmd[9] = uid[1]; //0x05;
-       cmd[10] = uid[0]; //0xe0;
+       cmd[2] = uid[7]; //0x32;
+       cmd[3] = uid[6]; //0x4b;
+       cmd[4] = uid[5]; //0x03;
+       cmd[5] = uid[4]; //0x01;
+       cmd[6] = uid[3]; //0x00;
+       cmd[7] = uid[2]; //0x10;
+       cmd[8] = uid[1]; //0x05;
+       cmd[9] = uid[0]; //0xe0;
        //Now the CRC
        crc = Crc(cmd, 10);
        //Now the CRC
        crc = Crc(cmd, 10);
-       cmd[11] = crc & 0xff;
-       cmd[12] = crc >> 8;
+       cmd[10] = crc & 0xff;
+       cmd[11] = crc >> 8;
 
        CodeIso15693AsReader(cmd, sizeof(cmd));
 }
 
        CodeIso15693AsReader(cmd, sizeof(cmd));
 }
@@ -1124,9 +1111,6 @@ void SimTagIso15693(uint32_t parameter, uint8_t *uid)
        
        memset(buf, 0x00, 100);
        
        
        memset(buf, 0x00, 100);
        
-       // Inventory response
-       BuildInventoryResponse(uid);
-       
        FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
 
        SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
        FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
 
        SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
@@ -1149,6 +1133,9 @@ void SimTagIso15693(uint32_t parameter, uint8_t *uid)
        {
                // Build a suitable reponse to the reader INVENTORY cocmmand
                // not so obsvious, but in the call to BuildInventoryResponse,  the command is copied to the global ToSend buffer used below.
        {
                // Build a suitable reponse to the reader INVENTORY cocmmand
                // not so obsvious, but in the call to BuildInventoryResponse,  the command is copied to the global ToSend buffer used below.
+               
+               BuildInventoryResponse(uid);
+       
                TransmitTo15693Reader(ToSend, ToSendMax, &tsamples, &wait);
        }
 
                TransmitTo15693Reader(ToSend, ToSendMax, &tsamples, &wait);
        }
 
@@ -1156,6 +1143,10 @@ void SimTagIso15693(uint32_t parameter, uint8_t *uid)
                buf[0], buf[1], buf[2], buf[3],
                buf[4], buf[5], buf[6], buf[7], buf[8]);
 
                buf[0], buf[1], buf[2], buf[3],
                buf[4], buf[5], buf[6], buf[7], buf[8]);
 
+       Dbprintf("Simulationg uid: %x %x %x %x %x %x %x %x",
+               uid[0], uid[1], uid[2], uid[3],
+               uid[4], uid[5], uid[6], uid[7]);
+
        LED_A_OFF();
        LED_B_OFF();
        LED_C_OFF();
        LED_A_OFF();
        LED_B_OFF();
        LED_C_OFF();
index c80caf776b323d600453b62c557c5f4e4d90778f..dc5efe68061d408fbdb0f58634a853de635bb6a0 100644 (file)
@@ -456,21 +456,30 @@ void SimulateTagLowFrequency(int period, int gap, int ledcontrol)
 
        FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
        FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
 
        FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
        FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
-       FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT);
-       SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
-
+       //FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT);
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU);
+       
+       // Connect the A/D to the peak-detected low-frequency path.
+       //SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
+               
        // Configure output and enable pin that is connected to the FPGA (for modulating)
        AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT | GPIO_SSC_CLK;    
        // Configure output and enable pin that is connected to the FPGA (for modulating)
        AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT | GPIO_SSC_CLK;    
-       AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT;
-       
-       AT91C_BASE_PIOA->PIO_ODR = GPIO_SSC_CLK;
+       AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT;    // (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
 
        // Give it a bit of time for the resonant antenna to settle.
 
        // Give it a bit of time for the resonant antenna to settle.
-       SpinDelay(30);
+       SpinDelay(150);
+       
+       while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)); // wait for ssp_clk to go high
+       while(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK);    // wait for ssp_clk to go low
+       
+       while(!BUTTON_PRESS()) { 
+               WDT_HIT();
 
 
-       for(;;) { 
-               
-               while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) {
+               // PIO_PDSR = Pin Data Status Register  
+               // GPIO_SSC_CLK  = SSC Transmit Clock
+               while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) {    // wait for ssp_clk to go high
                         if(BUTTON_PRESS()) {
                                 DbpString("Stopped at 0");
                                 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
                         if(BUTTON_PRESS()) {
                                 DbpString("Stopped at 0");
                                 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
@@ -479,12 +488,21 @@ void SimulateTagLowFrequency(int period, int gap, int ledcontrol)
                         WDT_HIT();
                }
         
                         WDT_HIT();
                }
         
-               if ( buff[i] )
-                       OPEN_COIL();
-               else
-                       SHORT_COIL();
-       
-                while(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK) {
+               // PIO_CODR = Clear Output Data Register
+               // PIO_SODR = Set Output Data Register
+               //#define LOW(x)         AT91C_BASE_PIOA->PIO_CODR = (x)
+               //#define HIGH(x)        AT91C_BASE_PIOA->PIO_SODR = (x)
+               
+               if ( buff[i] > 0 ){
+                       HIGH(GPIO_SSC_DOUT);
+                       //FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
+                       //FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU);
+               } else {
+                       LOW(GPIO_SSC_DOUT);
+                       //FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); 
+               }
+          
+                while(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK) {   // wait for ssp_clk to go low
                         if(BUTTON_PRESS()) {
                                DbpString("Stopped at 1");
                                FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
                         if(BUTTON_PRESS()) {
                                DbpString("Stopped at 1");
                                FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
@@ -492,18 +510,23 @@ void SimulateTagLowFrequency(int period, int gap, int ledcontrol)
                        }
                        WDT_HIT();
                 }
                        }
                        WDT_HIT();
                 }
-        
+               
+               //SpinDelayUs(512);
+               
                ++i;
                if(i == period) {
                        i = 0;
                        if (gap) {
                                // turn of modulation
                ++i;
                if(i == period) {
                        i = 0;
                        if (gap) {
                                // turn of modulation
-                               SHORT_COIL();
+                               LOW(GPIO_SSC_DOUT);
                                // wait
                                SpinDelay(gap);
                        } 
                }
        }
                                // wait
                                SpinDelay(gap);
                        } 
                }
        }
+       DbpString("Stopped");
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+       return;
 }
 
 #define DEBUG_FRAME_CONTENTS 1
 }
 
 #define DEBUG_FRAME_CONTENTS 1
index b01b45ba02c582f9bc209f0a8feff1d3a7c936c8..1df3486d4b297cb15779eadee20a9618a5efad27 100644 (file)
@@ -21,6 +21,7 @@
 #include "cmdmain.h"
 #include "cmddata.h"
 
 #include "cmdmain.h"
 #include "cmddata.h"
 
+
 static int CmdHelp(const char *Cmd);
 
 int CmdAmp(const char *Cmd)
 static int CmdHelp(const char *Cmd);
 
 int CmdAmp(const char *Cmd)
@@ -670,7 +671,9 @@ int CmdManchesterDemod(const char *Cmd)
     // At this stage, we now have a bitstream of "01" ("1") or "10" ("0"), parse it into final decoded bitstream
     // Actually, we overwrite BitStream with the new decoded bitstream, we just need to be careful
     // to stop output at the final bitidx2 value, not bitidx
     // At this stage, we now have a bitstream of "01" ("1") or "10" ("0"), parse it into final decoded bitstream
     // Actually, we overwrite BitStream with the new decoded bitstream, we just need to be careful
     // to stop output at the final bitidx2 value, not bitidx
-    for (i = 0; i < bitidx; i += 2) {
+       
+       //http://www.proxmark.org/forum/viewtopic.php?id=403
+    for (i = 1; i < bitidx; i += 2) {
       if ((BitStream[i] == 0) && (BitStream[i+1] == 1)) {
         BitStream[bit2idx++] = 1 ^ invert;
     } else if ((BitStream[i] == 1) && (BitStream[i+1] == 0)) {
       if ((BitStream[i] == 0) && (BitStream[i+1] == 1)) {
         BitStream[bit2idx++] = 1 ^ invert;
     } else if ((BitStream[i] == 1) && (BitStream[i+1] == 0)) {
@@ -713,7 +716,7 @@ int CmdManchesterDemod(const char *Cmd)
       BitStream[i+14],
       BitStream[i+15]);
   }
       BitStream[i+14],
       BitStream[i+15]);
   }
-  return 0;
+  return bit2idx;
 }
 
 /* Modulate our data into manchester */
 }
 
 /* Modulate our data into manchester */
@@ -884,7 +887,7 @@ static command_t CommandTable[] =
 {
   {"help",          CmdHelp,            1, "This help"},
   {"amp",           CmdAmp,             1, "Amplify peaks"},
 {
   {"help",          CmdHelp,            1, "This help"},
   {"amp",           CmdAmp,             1, "Amplify peaks"},
-  {"askdemod",      Cmdaskdemod,        1, "<0 or 1> -- Attempt to demodulate simple ASK tags"},
+  {"askdemod",      Cmdaskdemod,        1, "<0|1> -- Attempt to demodulate simple ASK tags"},
   {"autocorr",      CmdAutoCorr,        1, "<window length> -- Autocorrelation over window"},
   {"bitsamples",    CmdBitsamples,      0, "Get raw samples as bitstring"},
   {"bitstream",     CmdBitstream,       1, "[clock rate] -- Convert waveform into a bitstream"},
   {"autocorr",      CmdAutoCorr,        1, "<window length> -- Autocorrelation over window"},
   {"bitsamples",    CmdBitsamples,      0, "Get raw samples as bitstring"},
   {"bitstream",     CmdBitstream,       1, "[clock rate] -- Convert waveform into a bitstream"},
index bd19cee41990aa1056852854450a4f1dd53c5382..0f2b52227b43f93bf8d8268d249e58634d5bcd5d 100644 (file)
@@ -202,6 +202,7 @@ int CmdHF14AReader(const char *Cmd)
 
        switch (card->sak) {
                case 0x00: PrintAndLog("TYPE : NXP MIFARE Ultralight | Ultralight C"); break;
 
        switch (card->sak) {
                case 0x00: PrintAndLog("TYPE : NXP MIFARE Ultralight | Ultralight C"); break;
+               case 0x01: PrintAndLog("TYPE : NXP TNP3xxx  Activision Game Appliance"); break;
                case 0x04: PrintAndLog("TYPE : NXP MIFARE (various !DESFire !DESFire EV1)"); break;
                case 0x08: PrintAndLog("TYPE : NXP MIFARE CLASSIC 1k | Plus 2k SL1"); break;
                case 0x09: PrintAndLog("TYPE : NXP MIFARE Mini 0.3k"); break;
                case 0x04: PrintAndLog("TYPE : NXP MIFARE (various !DESFire !DESFire EV1)"); break;
                case 0x08: PrintAndLog("TYPE : NXP MIFARE CLASSIC 1k | Plus 2k SL1"); break;
                case 0x09: PrintAndLog("TYPE : NXP MIFARE Mini 0.3k"); break;
index 67013b2e813a483a1fc70853f752f51c1d4910f3..07f909ac392ae272761ae9535b93a3cd99953044 100644 (file)
@@ -127,7 +127,7 @@ retest:
         PrintAndLog("Thought we had a valid tag but failed at word %d (i=%d)", rows + 1, i);
 
         /* Start back rows * 5 + 9 header bits, -1 to not start at same place */
         PrintAndLog("Thought we had a valid tag but failed at word %d (i=%d)", rows + 1, i);
 
         /* Start back rows * 5 + 9 header bits, -1 to not start at same place */
-        i -= 9 + (5 * rows) -2;
+        i -= 9 + (5 * rows) -5;
 
         rows = header = 0;
       }
 
         rows = header = 0;
       }
@@ -220,11 +220,11 @@ int CmdEM410xSim(const char *Cmd)
   int clock = 64;
 
   /* clear our graph */
   int clock = 64;
 
   /* clear our graph */
-  ClearGraph(1);
+  ClearGraph(0);
   
   /* write it out a few times */
   
   /* write it out a few times */
-  for (h = 0; h < 4; h++)
-  {
+  //for (h = 0; h < 4; h++)
+  //{
     /* write 9 start bits */
     for (i = 0; i < 9; i++)
       AppendGraph(0, clock, 1);
     /* write 9 start bits */
     for (i = 0; i < 9; i++)
       AppendGraph(0, clock, 1);
@@ -262,10 +262,10 @@ int CmdEM410xSim(const char *Cmd)
 
     /* stop bit */
     AppendGraph(0, clock, 0);
 
     /* stop bit */
     AppendGraph(0, clock, 0);
-  }
+  //}
 
   /* modulate that biatch */
 
   /* modulate that biatch */
-  CmdManchesterMod("64");
+  //CmdManchesterMod("64");
 
   /* booyah! */
   RepaintGraphWindow();
 
   /* booyah! */
   RepaintGraphWindow();
@@ -295,7 +295,7 @@ int CmdEM410xWatch(const char *Cmd)
                }
                
                CmdLFRead(read_h ? "h" : "");
                }
                
                CmdLFRead(read_h ? "h" : "");
-               CmdSamples("16000");
+               CmdSamples("6000");
                
        } while (
                !CmdEM410xRead("") 
                
        } while (
                !CmdEM410xRead("") 
@@ -654,8 +654,10 @@ int CmdWriteWordPWD(const char *Cmd)
 static command_t CommandTable[] =
 {
   {"help", CmdHelp, 1, "This help"},
 static command_t CommandTable[] =
 {
   {"help", CmdHelp, 1, "This help"},
+  
   {"410xread", CmdEM410xRead, 1, "[clock rate] -- Extract ID from EM410x tag"},
   {"410xsim", CmdEM410xSim, 0, "<UID> -- Simulate EM410x tag"},
   {"410xread", CmdEM410xRead, 1, "[clock rate] -- Extract ID from EM410x tag"},
   {"410xsim", CmdEM410xSim, 0, "<UID> -- Simulate EM410x tag"},
+  {"replay",  MWRem4xReplay, 0, "Watches for tag and simulates manchester encoded em4x tag"},
   {"410xwatch", CmdEM410xWatch, 0, "['h'] -- Watches for EM410x 125/134 kHz tags (option 'h' for 134)"},
   {"410xspoof", CmdEM410xWatchnSpoof, 0, "['h'] --- Watches for EM410x 125/134 kHz tags, and replays them. (option 'h' for 134)" },
   {"410xwrite", CmdEM410xWrite, 1, "<UID> <'0' T5555> <'1' T55x7> [clock rate] -- Write EM410x UID to T5555(Q5) or T55x7 tag, optionally setting clock rate"},
   {"410xwatch", CmdEM410xWatch, 0, "['h'] -- Watches for EM410x 125/134 kHz tags (option 'h' for 134)"},
   {"410xspoof", CmdEM410xWatchnSpoof, 0, "['h'] --- Watches for EM410x 125/134 kHz tags, and replays them. (option 'h' for 134)" },
   {"410xwrite", CmdEM410xWrite, 1, "<UID> <'0' T5555> <'1' T55x7> [clock rate] -- Write EM410x UID to T5555(Q5) or T55x7 tag, optionally setting clock rate"},
@@ -667,6 +669,265 @@ static command_t CommandTable[] =
   {NULL, NULL, 0, NULL}
 };
 
   {NULL, NULL, 0, NULL}
 };
 
+
+//Confirms the parity of a bitstream as well as obtaining the data (TagID) from within the appropriate memory space.
+//Arguments:
+// Pointer to a string containing the desired bitsream
+// Pointer to a string that will receive the decoded tag ID
+// Length of the bitsream pointed at in the first argument, char* _strBitStream
+//Retuns:
+//1 Parity confirmed
+//0 Parity not confirmed
+int ConfirmEm410xTagParity( char* _strBitStream, char* pID, int LengthOfBitstream )
+{
+       int i = 0;
+       int rows = 0;
+       int Parity[4] = {0x00};
+       char ID[11] = {0x00};
+       int k = 0;
+       int BitStream[70] = {0x00};
+       int counter = 0;
+       //prepare variables
+       for ( i = 0; i <= LengthOfBitstream; i++)
+       {
+               if (_strBitStream[i] == '1')
+               {
+                       k =1;
+                       memcpy(&BitStream[i], &k,4);
+               }
+               else if (_strBitStream[i] == '0')
+               {
+                       k = 0;
+                       memcpy(&BitStream[i], &k,4);
+               }
+       }
+       while ( counter < 2 )
+       {
+               //set/reset variables and counters
+               memset(ID,0x00,sizeof(ID));
+               memset(Parity,0x00,sizeof(Parity));
+               rows = 0;
+               for ( i = 9; i <= LengthOfBitstream; i++)
+               {
+                       if ( rows < 10 )
+                       {
+                               if ((BitStream[i] ^ BitStream[i+1] ^ BitStream[i+2] ^ BitStream[i+3]) == BitStream[i+4])
+                               {
+                                       sprintf(ID+rows, "%x", (8 * BitStream[i]) + (4 * BitStream[i+1]) + (2 * BitStream[i+2]) + (1 * BitStream[i+3]));
+                                       rows++;
+                                       /* Keep parity info and move four bits ahead*/
+                                       Parity[0] ^= BitStream[i];
+                                       Parity[1] ^= BitStream[i+1];
+                                       Parity[2] ^= BitStream[i+2];
+                                       Parity[3] ^= BitStream[i+3];
+                                       i += 4;
+                               }
+                       }
+                       if ( rows == 10 )
+                       {
+                               if (    BitStream[i] == Parity[0] && BitStream[i+1] == Parity[1] &&
+                                       BitStream[i+2] == Parity[2] && BitStream[i+3] == Parity[3] &&
+                                       BitStream[i+4] == 0)
+                               {
+                                       memcpy(pID,ID,strlen(ID));
+                                       return 1;
+                               }
+                       }
+               }
+               printf("[PARITY ->]Failed. Flipping Bits, and rechecking parity for bitstream:\n[PARITY ->]");  
+               for (k = 0; k < LengthOfBitstream; k++)
+               {
+                       BitStream[k] ^= 1;
+                       printf("%i", BitStream[k]);
+               }
+               puts(" ");
+               counter++;
+       }
+       return 0;
+}
+//Reads and demodulates an em410x RFID tag. It further allows slight modification to the decoded bitstream
+//Once a suitable bitstream has been identified, and if needed, modified, it is replayed. Allowing emulation of the
+//"stolen" rfid tag.
+//No meaningful returns or arguments.
+int MWRem4xReplay(const char* Cmd)
+{
+       // //header traces
+       // static char ArrayTraceZero[] = { '0','0','0','0','0','0','0','0','0' };
+       // static char ArrayTraceOne[] =  { '1','1','1','1','1','1','1','1','1' };
+       // //local string variables
+       // char strClockRate[10] = {0x00};
+       // char strAnswer[4] = {0x00};
+       // char strTempBufferMini[2] = {0x00}; 
+       // //our outbound bit-stream
+       // char strSimulateBitStream[65] = {0x00};
+       // //integers
+       // int iClockRate = 0;
+       // int needle = 0;
+       // int j = 0;
+       // int iFirstHeaderOffset = 0x00000000;
+       // int numManchesterDemodBits=0;
+       // //boolean values
+       // bool bInverted = false;
+       // //pointers to strings. memory will be allocated.
+       // char* pstrInvertBitStream = 0x00000000;
+       // char* pTempBuffer = 0x00000000;
+       // char* pID = 0x00000000;
+       // char* strBitStreamBuffer = 0x00000000;
+               
+
+       // puts("###################################");
+       // puts("#### Em4x Replay                 ##");
+       // puts("#### R.A.M.           June 2013  ##");
+       // puts("###################################");
+       // //initialize
+       // CmdLFRead("");
+       // //Collect ourselves 10,000 samples
+       // CmdSamples("10000");
+       // puts("[->]preforming ASK demodulation\n");
+       // //demodulate ask
+       // Cmdaskdemod("0");
+       // iClockRate = DetectClock(0);
+       // sprintf(strClockRate, "%i\n",iClockRate);
+       // printf("[->]Detected ClockRate: %s\n", strClockRate);
+       
+       // //If detected clock rate is something completely unreasonable, dont go ahead
+       // if ( iClockRate < 0xFFFE )
+       // {  
+           // pTempBuffer = (char*)malloc(MAX_GRAPH_TRACE_LEN);
+           // if (pTempBuffer == 0x00000000)
+             // return 0;
+           // memset(pTempBuffer,0x00,MAX_GRAPH_TRACE_LEN);
+           // //Preform manchester de-modulation and display in a single line.
+           // numManchesterDemodBits = CmdManchesterDemod( strClockRate ); 
+           // //note: numManchesterDemodBits is set above in CmdManchesterDemod()
+           // if ( numManchesterDemodBits == 0 )
+             // return 0;
+           // strBitStreamBuffer = malloc(numManchesterDemodBits+1);
+           // if ( strBitStreamBuffer == 0x00000000 )
+               // return 0;
+           // memset(strBitStreamBuffer, 0x00, (numManchesterDemodBits+1));
+           // //fill strBitStreamBuffer with demodulated, string formatted bits.
+           // for ( j = 0; j <= numManchesterDemodBits; j++ )
+           // {
+               // sprintf(strTempBufferMini, "%i",BitStream[j]);
+               // strcat(strBitStreamBuffer,strTempBufferMini);
+           // }
+           // printf("[->]Demodulated Bitstream: \n%s\n", strBitStreamBuffer);
+           // //Reset counter and select most probable bit stream
+           // j = 0;
+               // while ( j < numManchesterDemodBits )
+               // {
+                   // memset(strSimulateBitStream,0x00,64);
+                   // //search for header of nine (9) 0's : 000000000 or nine (9) 1's : 1111 1111 1
+                       // if ( ( strncmp(strBitStreamBuffer+j, ArrayTraceZero, sizeof(ArrayTraceZero)) == 0 ) ||
+                           // ( strncmp(strBitStreamBuffer+j, ArrayTraceOne, sizeof(ArrayTraceOne)) == 0  ) )
+                       // {
+                               // iFirstHeaderOffset = j;
+                           // memcpy(strSimulateBitStream, strBitStreamBuffer+j,64);
+                           // printf("[->]Offset of Header");
+                               // if ( strncmp(strBitStreamBuffer+iFirstHeaderOffset, "0", 1) == 0 )
+                                       // printf("'%s'", ArrayTraceZero );
+                               // else
+                                       // printf("'%s'", ArrayTraceOne );
+                               // printf(": %i\nHighlighted string : %s\n",iFirstHeaderOffset,strSimulateBitStream);
+                           // //allow us to escape loop or choose another frame
+                           // puts("[<-]Are we happy with this sample? [Y]es/[N]o");
+                           // gets(strAnswer);
+                           // if ( ( strncmp(strAnswer,"y",1) == 0 )  || ( strncmp(strAnswer,"Y",1) == 0 ) )
+                           // {
+                                   // j = numManchesterDemodBits+1;
+                                   // break;
+                           // }
+                       // }
+                       // j++;
+               // }
+       // }
+       // else return 0;
+       
+       // //Do we want the buffer inverted?
+       // memset(strAnswer, 0x00, sizeof(strAnswer));
+       // printf("[<-]Do you wish to invert the highlighted bitstream? [Y]es/[N]o\n");
+       // gets(strAnswer);
+       // if ( ( strncmp("y", strAnswer,1) == 0 )  || ( strncmp("Y", strAnswer, 1 ) == 0 ) )
+       // {
+               // //allocate heap memory
+               // pstrInvertBitStream = (char*)malloc(numManchesterDemodBits);
+               // if ( pstrInvertBitStream != 0x00000000 )
+               // {
+                       // memset(pstrInvertBitStream,0x00,numManchesterDemodBits);
+                       // bInverted = true;
+                       // //Invert Bitstream
+                       // for ( needle = 0; needle <= numManchesterDemodBits; needle++ )
+                       // {
+                               // if (strSimulateBitStream[needle] == '0')
+                                       // strcat(pstrInvertBitStream,"1");
+                               // else if (strSimulateBitStream[needle] == '1')
+                                       // strcat(pstrInvertBitStream,"0");
+                       // }
+                       // printf("[->]Inverted bitstream: %s\n", pstrInvertBitStream);
+               // }
+       // }    
+    // //Confirm parity of selected string
+       // pID = (char*)malloc(11);
+       // if (pID != 0x00000000)
+       // {
+               // memset(pID, 0x00, 11);
+               // if (ConfirmEm410xTagParity(strSimulateBitStream,pID, 64) == 1)
+               // {
+                       // printf("[->]Parity confirmed for selected bitstream!\n");
+                       // printf("[->]Tag ID was detected as: [hex]:%s\n",pID );
+               // }
+               // else
+                       // printf("[->]Parity check failed for the selected bitstream!\n");     
+       // }
+       
+       // //Spoof
+       // memset(strAnswer, 0x00, sizeof(strAnswer));  
+       // printf("[<-]Do you wish to continue with the EM4x simulation? [Y]es/[N]o\n");
+       // gets(strAnswer);
+       // if ( ( strncmp(strAnswer,"y",1) == 0 )  || ( strncmp(strAnswer,"Y",1) == 0 ) )
+       // {
+               // strcat(pTempBuffer, strClockRate);
+               // strcat(pTempBuffer, " ");
+               // if (bInverted == true)
+                       // strcat(pTempBuffer,pstrInvertBitStream);
+               // if (bInverted == false)
+                       // strcat(pTempBuffer,strSimulateBitStream);
+               // //inform the user
+               // puts("[->]Starting simulation now: \n");
+               // //Simulate tag with prepared buffer.
+               // CmdLFSimManchester(pTempBuffer);
+       // }
+       // else if ( ( strcmp("n", strAnswer) == 0 )  || ( strcmp("N", strAnswer ) == 0 ) )
+               // printf("[->]Exiting procedure now...\n");
+       // else
+               // printf("[->]Erroneous selection\nExiting procedure now....\n");
+       
+       // //Clean up -- Exit function
+       // //clear memory, then release pointer.
+       // if ( pstrInvertBitStream != 0x00000000 )
+       // {
+           // memset(pstrInvertBitStream,0x00,numManchesterDemodBits);
+           // free(pstrInvertBitStream);
+       // }
+       // if ( pTempBuffer != 0x00000000 )
+       // {
+           // memset(pTempBuffer,0x00,MAX_GRAPH_TRACE_LEN);
+           // free(pTempBuffer);
+       // }
+       // if ( pID != 0x00000000 )
+       // {
+           // memset(pID,0x00,11);
+           // free(pID);
+       // }
+       // if ( strBitStreamBuffer != 0x00000000 )
+       // {
+           // memset(strBitStreamBuffer,0x00,numManchesterDemodBits);
+           // free(strBitStreamBuffer);
+       // }
+       return 0;
+}
+
 int CmdLFEM4X(const char *Cmd)
 {
   CmdsParse(CommandTable, Cmd);
 int CmdLFEM4X(const char *Cmd)
 {
   CmdsParse(CommandTable, Cmd);
index a209e8f92d9b3791fab4e52a3db208804429a2b6..587dbf7f632f677b2a9e5d5fcfa9433728b7104c 100644 (file)
@@ -22,5 +22,6 @@ int CmdReadWord(const char *Cmd);
 int CmdReadWordPWD(const char *Cmd);
 int CmdWriteWord(const char *Cmd);
 int CmdWriteWordPWD(const char *Cmd);
 int CmdReadWordPWD(const char *Cmd);
 int CmdWriteWord(const char *Cmd);
 int CmdWriteWordPWD(const char *Cmd);
+int MWRem4xReplay(const char* Cmd);
 
 #endif
 
 #endif
index 4e8cb89cc2f287d3577cf67acee5f23e20c07cee..7b45f3f2f1cf00d1df8bf1295fdb04d0dafd79b2 100644 (file)
@@ -89,6 +89,9 @@ int DetectClock(int peak)
                case 1: clock--; break;
                case 2: clock -= 2; break;
        }
                case 1: clock--; break;
                case 2: clock -= 2; break;
        }
+       if ( clock < 32) 
+               clock = 32;
+               
        printf("- adjusted it to %d \n", clock);
        return clock;
 }
        printf("- adjusted it to %d \n", clock);
        return clock;
 }
index a52abdef7c41a530dc12dace4ff48b782c3a828f..b468eb2dbb3c01848040d9b7fadcbb61b97513e1 100644 (file)
@@ -55,6 +55,7 @@ local skel_1 = [[
                        return "UNKNOWN"
                }
 
                        return "UNKNOWN"
                }
 
+               add("04,,,Mifare TNP3xxx Activision 1K,0f01,01");
                add("04,,,Mifare Mini,0004,09");
                add("04,,,Mifare Classic 1k/Mifare Plus(4 byte UID) 2K SL1,0004,08");
                add("04,,,Mifare Plus (4 byte UID) 2K SL2,0004,10");
                add("04,,,Mifare Mini,0004,09");
                add("04,,,Mifare Classic 1k/Mifare Plus(4 byte UID) 2K SL1,0004,08");
                add("04,,,Mifare Plus (4 byte UID) 2K SL2,0004,10");
diff --git a/client/lualibs/md5.lua b/client/lualibs/md5.lua
new file mode 100644 (file)
index 0000000..2390f95
--- /dev/null
@@ -0,0 +1,384 @@
+local md5 = {
+  _VERSION     = "md5.lua 0.5.0",
+  _DESCRIPTION = "MD5 computation in Lua (5.1)",
+  _URL         = "https://github.com/kikito/md5.lua",
+  _LICENSE     = [[
+    MIT LICENSE
+
+    Copyright (c) 2013 Enrique García Cota + Adam Baldwin + hanzao + Equi 4 Software
+
+    Permission is hereby granted, free of charge, to any person obtaining a
+    copy of this software and associated documentation files (the
+    "Software"), to deal in the Software without restriction, including
+    without limitation the rights to use, copy, modify, merge, publish,
+    distribute, sublicense, and/or sell copies of the Software, and to
+    permit persons to whom the Software is furnished to do so, subject to
+    the following conditions:
+
+    The above copyright notice and this permission notice shall be included
+    in all copies or substantial portions of the Software.
+
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+    IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+    CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+    TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+    SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+  ]]
+}
+
+-- bit lib implementions
+
+local floor, abs, max = math.floor, math.abs, math.max
+local char, byte, format, rep, sub =
+  string.char, string.byte, string.format, string.rep, string.sub
+
+local function check_int(n)
+  -- checking not float
+  if(n - floor(n) > 0) then
+    error("trying to use bitwise operation on non-integer!")
+  end
+end
+
+local function tbl2number(tbl)
+  local n = #tbl
+
+  local rslt = 0
+  local power = 1
+  for i = 1, n do
+    rslt = rslt + tbl[i]*power
+    power = power*2
+  end
+
+  return rslt
+end
+
+local function expand(tbl_m, tbl_n)
+  local big = {}
+  local small = {}
+  if(#tbl_m > #tbl_n) then
+    big = tbl_m
+    small = tbl_n
+  else
+    big = tbl_n
+    small = tbl_m
+  end
+  -- expand small
+  for i = #small + 1, #big do
+    small[i] = 0
+  end
+
+end
+
+local to_bits -- needs to be declared before bit_not
+
+local function bit_not(n)
+  local tbl = to_bits(n)
+  local size = max(#tbl, 32)
+  for i = 1, size do
+    if(tbl[i] == 1) then
+      tbl[i] = 0
+    else
+      tbl[i] = 1
+    end
+  end
+  return tbl2number(tbl)
+end
+
+-- defined as local above
+to_bits = function (n)
+  check_int(n)
+  if(n < 0) then
+    -- negative
+    return to_bits(bit_not(abs(n)) + 1)
+  end
+  -- to bits table
+  local tbl = {}
+  local cnt = 1
+  while (n > 0) do
+    local last = math.fmod(n,2)
+    if(last == 1) then
+      tbl[cnt] = 1
+    else
+      tbl[cnt] = 0
+    end
+    n = (n-last)/2
+    cnt = cnt + 1
+  end
+
+  return tbl
+end
+
+local function bit_or(m, n)
+  local tbl_m = to_bits(m)
+  local tbl_n = to_bits(n)
+  expand(tbl_m, tbl_n)
+
+  local tbl = {}
+  local rslt = max(#tbl_m, #tbl_n)
+  for i = 1, rslt do
+    if(tbl_m[i]== 0 and tbl_n[i] == 0) then
+      tbl[i] = 0
+    else
+      tbl[i] = 1
+    end
+  end
+
+  return tbl2number(tbl)
+end
+
+local function bit_and(m, n)
+  local tbl_m = to_bits(m)
+  local tbl_n = to_bits(n)
+  expand(tbl_m, tbl_n)
+
+  local tbl = {}
+  local rslt = max(#tbl_m, #tbl_n)
+  for i = 1, rslt do
+    if(tbl_m[i]== 0 or tbl_n[i] == 0) then
+      tbl[i] = 0
+    else
+      tbl[i] = 1
+    end
+  end
+
+  return tbl2number(tbl)
+end
+
+local function bit_xor(m, n)
+  local tbl_m = to_bits(m)
+  local tbl_n = to_bits(n)
+  expand(tbl_m, tbl_n)
+
+  local tbl = {}
+  local rslt = max(#tbl_m, #tbl_n)
+  for i = 1, rslt do
+    if(tbl_m[i] ~= tbl_n[i]) then
+      tbl[i] = 1
+    else
+      tbl[i] = 0
+    end
+  end
+
+  return tbl2number(tbl)
+end
+
+local function bit_rshift(n, bits)
+  check_int(n)
+
+  local high_bit = 0
+  if(n < 0) then
+    -- negative
+    n = bit_not(abs(n)) + 1
+    high_bit = 2147483648 -- 0x80000000
+  end
+
+  for i=1, bits do
+    n = n/2
+    n = bit_or(floor(n), high_bit)
+  end
+  return floor(n)
+end
+
+local function bit_lshift(n, bits)
+  check_int(n)
+
+  if(n < 0) then
+    -- negative
+    n = bit_not(abs(n)) + 1
+  end
+
+  for i=1, bits do
+    n = n*2
+  end
+  return bit_and(n, 4294967295) -- 0xFFFFFFFF
+end
+
+-- convert little-endian 32-bit int to a 4-char string
+local function lei2str(i)
+  local f=function (s) return char( bit_and( bit_rshift(i, s), 255)) end
+  return f(0)..f(8)..f(16)..f(24)
+end
+
+-- convert raw string to big-endian int
+local function str2bei(s)
+  local v=0
+  for i=1, #s do
+    v = v * 256 + byte(s, i)
+  end
+  return v
+end
+
+-- convert raw string to little-endian int
+local function str2lei(s)
+  local v=0
+  for i = #s,1,-1 do
+    v = v*256 + byte(s, i)
+  end
+  return v
+end
+
+-- cut up a string in little-endian ints of given size
+local function cut_le_str(s,...)
+  local o, r = 1, {}
+  local args = {...}
+  for i=1, #args do
+    table.insert(r, str2lei(sub(s, o, o + args[i] - 1)))
+    o = o + args[i]
+  end
+  return r
+end
+
+local swap = function (w) return str2bei(lei2str(w)) end
+
+local function hex2binaryaux(hexval)
+  return char(tonumber(hexval, 16))
+end
+
+local function hex2binary(hex)
+  local result, _ = hex:gsub('..', hex2binaryaux)
+  return result
+end
+
+-- An MD5 mplementation in Lua, requires bitlib (hacked to use LuaBit from above, ugh)
+-- 10/02/2001 jcw@equi4.com
+
+local FF     = 0xffffffff
+local CONSTS = {
+  0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
+  0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
+  0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
+  0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
+  0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
+  0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
+  0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
+  0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
+  0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
+  0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
+  0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
+  0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
+  0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
+  0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
+  0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
+  0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391,
+  0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476
+}
+
+local f=function (x,y,z) return bit_or(bit_and(x,y),bit_and(-x-1,z)) end
+local g=function (x,y,z) return bit_or(bit_and(x,z),bit_and(y,-z-1)) end
+local h=function (x,y,z) return bit_xor(x,bit_xor(y,z)) end
+local i=function (x,y,z) return bit_xor(y,bit_or(x,-z-1)) end
+local z=function (f,a,b,c,d,x,s,ac)
+  a=bit_and(a+f(b,c,d)+x+ac,FF)
+  -- be *very* careful that left shift does not cause rounding!
+  return bit_or(bit_lshift(bit_and(a,bit_rshift(FF,s)),s),bit_rshift(a,32-s))+b
+end
+
+local function transform(A,B,C,D,X)
+  local a,b,c,d=A,B,C,D
+  local t=CONSTS
+
+  a=z(f,a,b,c,d,X[ 0], 7,t[ 1])
+  d=z(f,d,a,b,c,X[ 1],12,t[ 2])
+  c=z(f,c,d,a,b,X[ 2],17,t[ 3])
+  b=z(f,b,c,d,a,X[ 3],22,t[ 4])
+  a=z(f,a,b,c,d,X[ 4], 7,t[ 5])
+  d=z(f,d,a,b,c,X[ 5],12,t[ 6])
+  c=z(f,c,d,a,b,X[ 6],17,t[ 7])
+  b=z(f,b,c,d,a,X[ 7],22,t[ 8])
+  a=z(f,a,b,c,d,X[ 8], 7,t[ 9])
+  d=z(f,d,a,b,c,X[ 9],12,t[10])
+  c=z(f,c,d,a,b,X[10],17,t[11])
+  b=z(f,b,c,d,a,X[11],22,t[12])
+  a=z(f,a,b,c,d,X[12], 7,t[13])
+  d=z(f,d,a,b,c,X[13],12,t[14])
+  c=z(f,c,d,a,b,X[14],17,t[15])
+  b=z(f,b,c,d,a,X[15],22,t[16])
+
+  a=z(g,a,b,c,d,X[ 1], 5,t[17])
+  d=z(g,d,a,b,c,X[ 6], 9,t[18])
+  c=z(g,c,d,a,b,X[11],14,t[19])
+  b=z(g,b,c,d,a,X[ 0],20,t[20])
+  a=z(g,a,b,c,d,X[ 5], 5,t[21])
+  d=z(g,d,a,b,c,X[10], 9,t[22])
+  c=z(g,c,d,a,b,X[15],14,t[23])
+  b=z(g,b,c,d,a,X[ 4],20,t[24])
+  a=z(g,a,b,c,d,X[ 9], 5,t[25])
+  d=z(g,d,a,b,c,X[14], 9,t[26])
+  c=z(g,c,d,a,b,X[ 3],14,t[27])
+  b=z(g,b,c,d,a,X[ 8],20,t[28])
+  a=z(g,a,b,c,d,X[13], 5,t[29])
+  d=z(g,d,a,b,c,X[ 2], 9,t[30])
+  c=z(g,c,d,a,b,X[ 7],14,t[31])
+  b=z(g,b,c,d,a,X[12],20,t[32])
+
+  a=z(h,a,b,c,d,X[ 5], 4,t[33])
+  d=z(h,d,a,b,c,X[ 8],11,t[34])
+  c=z(h,c,d,a,b,X[11],16,t[35])
+  b=z(h,b,c,d,a,X[14],23,t[36])
+  a=z(h,a,b,c,d,X[ 1], 4,t[37])
+  d=z(h,d,a,b,c,X[ 4],11,t[38])
+  c=z(h,c,d,a,b,X[ 7],16,t[39])
+  b=z(h,b,c,d,a,X[10],23,t[40])
+  a=z(h,a,b,c,d,X[13], 4,t[41])
+  d=z(h,d,a,b,c,X[ 0],11,t[42])
+  c=z(h,c,d,a,b,X[ 3],16,t[43])
+  b=z(h,b,c,d,a,X[ 6],23,t[44])
+  a=z(h,a,b,c,d,X[ 9], 4,t[45])
+  d=z(h,d,a,b,c,X[12],11,t[46])
+  c=z(h,c,d,a,b,X[15],16,t[47])
+  b=z(h,b,c,d,a,X[ 2],23,t[48])
+
+  a=z(i,a,b,c,d,X[ 0], 6,t[49])
+  d=z(i,d,a,b,c,X[ 7],10,t[50])
+  c=z(i,c,d,a,b,X[14],15,t[51])
+  b=z(i,b,c,d,a,X[ 5],21,t[52])
+  a=z(i,a,b,c,d,X[12], 6,t[53])
+  d=z(i,d,a,b,c,X[ 3],10,t[54])
+  c=z(i,c,d,a,b,X[10],15,t[55])
+  b=z(i,b,c,d,a,X[ 1],21,t[56])
+  a=z(i,a,b,c,d,X[ 8], 6,t[57])
+  d=z(i,d,a,b,c,X[15],10,t[58])
+  c=z(i,c,d,a,b,X[ 6],15,t[59])
+  b=z(i,b,c,d,a,X[13],21,t[60])
+  a=z(i,a,b,c,d,X[ 4], 6,t[61])
+  d=z(i,d,a,b,c,X[11],10,t[62])
+  c=z(i,c,d,a,b,X[ 2],15,t[63])
+  b=z(i,b,c,d,a,X[ 9],21,t[64])
+
+  return A+a,B+b,C+c,D+d
+end
+
+----------------------------------------------------------------
+
+function md5.sumhexa(s)
+  local msgLen = #s
+  local padLen = 56 - msgLen % 64
+
+  if msgLen % 64 > 56 then padLen = padLen + 64 end
+
+  if padLen == 0 then padLen = 64 end
+
+  s = s .. char(128) .. rep(char(0),padLen-1) .. lei2str(8*msgLen) .. lei2str(0)
+
+  assert(#s % 64 == 0)
+
+  local t = CONSTS
+  local a,b,c,d = t[65],t[66],t[67],t[68]
+
+  for i=1,#s,64 do
+    local X = cut_le_str(sub(s,i,i+63),4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4)
+    assert(#X == 16)
+    X[0] = table.remove(X,1) -- zero based!
+    a,b,c,d = transform(a,b,c,d,X)
+  end
+
+  return format("%08x%08x%08x%08x",swap(a),swap(b),swap(c),swap(d))
+end
+
+function md5.sum(s)
+  return hex2binary(md5.sumhexa(s))
+end
+
+return md5
index 4859ff0c1781dd200aee59e232f89b4771284d4c..b9b414d8704c1051d316d60551f91dd1f8e64da0 100644 (file)
@@ -141,7 +141,13 @@ local _keys = {
        '200000000000',
        'a00000000000',
        'b00000000000', 
        '200000000000',
        'a00000000000',
        'b00000000000', 
-  }
+       
+       --[[
+    Should be for Mifare TNP3xxx tags A KEY.
+    --]]
+       '4b0b20107ccb',
+
+}
 
 ---
 --    The keys above have just been pasted in, for completeness sake. They contain duplicates. 
 
 ---
 --    The keys above have just been pasted in, for completeness sake. They contain duplicates. 
index 24021a1dcbfeae192d3b50567cb667dc13025c29..10e7c2d4a929b05ba29c9e32e841f569e9d0a8c6 100644 (file)
@@ -25,6 +25,7 @@ local ISO14A_COMMAND = {
 
 local ISO14443a_TYPES = {}             
 ISO14443a_TYPES[0x00] = "NXP MIFARE Ultralight | Ultralight C"
 
 local ISO14443a_TYPES = {}             
 ISO14443a_TYPES[0x00] = "NXP MIFARE Ultralight | Ultralight C"
+ISO14443a_TYPES[0x01] = "NXP MIFARE TNP3xxx Activision Game Appliance"
 ISO14443a_TYPES[0x04] = "NXP MIFARE (various !DESFire !DESFire EV1)"
 ISO14443a_TYPES[0x08] = "NXP MIFARE CLASSIC 1k | Plus 2k"
 ISO14443a_TYPES[0x09] = "NXP MIFARE Mini 0.3k"
 ISO14443a_TYPES[0x04] = "NXP MIFARE (various !DESFire !DESFire EV1)"
 ISO14443a_TYPES[0x08] = "NXP MIFARE CLASSIC 1k | Plus 2k"
 ISO14443a_TYPES[0x09] = "NXP MIFARE Mini 0.3k"
index 963bb64c2b0dd616595671eb5923f5bc9c8e5049..fd065a044d7da49983dd57de781fa742e25a16bd 100644 (file)
@@ -18,6 +18,7 @@
 #include "util.h"
 #include "nonce2key/nonce2key.h"
 #include "../common/iso15693tools.h"
 #include "util.h"
 #include "nonce2key/nonce2key.h"
 #include "../common/iso15693tools.h"
+#include <openssl/aes.h>   
 /**
  * The following params expected:
  *  UsbCommand c
 /**
  * The following params expected:
  *  UsbCommand c
@@ -224,6 +225,44 @@ static int l_iso15693_crc(lua_State *L)
     return 1;
 }
 
     return 1;
 }
 
+/*
+ Simple AES 128 cbc hook up to OpenSSL.
+ params:  key, input
+*/
+static int l_aes(lua_State *L)
+{
+       //Check number of arguments
+       int i;
+    size_t size;
+    const char *p_key = luaL_checklstring(L, 1, &size);
+    if(size != 32)  return returnToLuaWithError(L,"Wrong size of key, got %d bytes, expected 32", (int) size);
+
+    const char *p_encTxt = luaL_checklstring(L, 2, &size);
+    
+       unsigned char indata[AES_BLOCK_SIZE] = {0x00};
+       unsigned char outdata[AES_BLOCK_SIZE] = {0x00};
+    unsigned char aes_key[AES_BLOCK_SIZE] = {0x00};
+       unsigned char iv[AES_BLOCK_SIZE] = {0x00};
+       
+       // convert key to bytearray
+       for (i = 0; i < 32; i += 2) {
+               sscanf(&p_encTxt[i], "%02x", (unsigned int *)&indata[i / 2]);
+       }
+       
+       // convert input to bytearray
+       for (i = 0; i < 32; i += 2) {
+               sscanf(&p_key[i], "%02x", (unsigned int *)&aes_key[i / 2]);
+       }
+       
+       AES_KEY key;
+       AES_set_decrypt_key(aes_key, 128, &key);
+    AES_cbc_encrypt(indata, outdata, sizeof(indata), &key, iv, AES_DECRYPT);
+
+    //Push decrypted array as a string
+       lua_pushlstring(L,(const char *)&outdata, sizeof(outdata));
+       return 1;// return 1 to signal one return value
+}
+
 /**
  * @brief Sets the lua path to include "./lualibs/?.lua", in order for a script to be
  * able to do "require('foobar')" if foobar.lua is within lualibs folder.
 /**
  * @brief Sets the lua path to include "./lualibs/?.lua", in order for a script to be
  * able to do "require('foobar')" if foobar.lua is within lualibs folder.
@@ -259,8 +298,9 @@ int set_pm3_libraries(lua_State *L)
         {"foobar",                      l_foobar},
         {"ukbhit",                      l_ukbhit},
         {"clearCommandBuffer",          l_clearCommandBuffer},
         {"foobar",                      l_foobar},
         {"ukbhit",                      l_ukbhit},
         {"clearCommandBuffer",          l_clearCommandBuffer},
-        {"console",                      l_CmdConsole},
-        {"iso15693_crc",                 l_iso15693_crc},
+        {"console",                     l_CmdConsole},
+        {"iso15693_crc",                l_iso15693_crc},
+               {"aes",                         l_aes},
         {NULL, NULL}
     };
 
         {NULL, NULL}
     };
 
index 8d0d358fa72590936992ac147dff9cab4c55d015..eb98ffbf753809d64188a47448286e5760735498 100644 (file)
@@ -133,6 +133,8 @@ function nested(key,sak)
                typ = 0
        elseif  0x10 == sak then-- "NXP MIFARE Plus 2k"
                typ = 2
                typ = 0
        elseif  0x10 == sak then-- "NXP MIFARE Plus 2k"
                typ = 2
+       elseif  0x01 == sak then-- "NXP MIFARE TNP3xxx 1K"
+               typ = 1
        else
                print("I don't know how many sectors there are on this type of card, defaulting to 16")
        end
        else
                print("I don't know how many sectors there are on this type of card, defaulting to 16")
        end
diff --git a/client/scripts/tnp3.lua b/client/scripts/tnp3.lua
new file mode 100644 (file)
index 0000000..3eb5af1
--- /dev/null
@@ -0,0 +1,189 @@
+local cmds = require('commands')
+local getopt = require('getopt')
+local bin = require('bin')
+local lib14a = require('read14a')
+local utils = require('utils')
+local md5 = require('md5')
+
+example =[[
+       1. script run tnp3
+       2. script run tnp3 -k aabbccddeeff
+]]
+author = "Iceman"
+usage = "script run tnp3 -k <key>"
+desc =[[
+This script will try to dump the contents of a Mifare TNP3xxx card.
+It will need a valid KeyA in order to find the other keys and decode the card.
+Arguments:
+       -h             - this help
+       -k <key>       - Sector 0 Key A.
+]]
+
+local hashconstant = '20436F707972696768742028432920323031302041637469766973696F6E2E20416C6C205269676874732052657365727665642E20'
+
+local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
+local DEBUG = true -- the debug flag
+local numBlocks = 64
+local numSectors = 16
+--- 
+-- A debug printout-function
+function dbg(args)
+       if not DEBUG then
+               return
+       end
+       
+    if type(args) == "table" then
+               local i = 1
+               while result[i] do
+                       dbg(result[i])
+                       i = i+1
+               end
+       else
+               print("###", args)
+       end     
+end    
+--- 
+-- This is only meant to be used when errors occur
+function oops(err)
+       print("ERROR: ",err)
+end
+--- 
+-- Usage help
+function help()
+       print(desc)
+       print("Example usage")
+       print(example)
+end
+--
+-- Exit message
+function ExitMsg(msg)
+       print( string.rep('--',20) )
+       print( string.rep('--',20) )
+       print(msg)
+       print()
+end
+
+local function show(data)
+       if DEBUG then
+           local formatString = ("H%d"):format(string.len(data))
+           local _,hexdata = bin.unpack(formatString, data)
+           dbg("Hexdata" , hexdata)
+       end
+end
+
+function waitCmd()
+       local response = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT)
+       if response then
+               local count,cmd,arg0 = bin.unpack('LL',response)
+               if(arg0==1) then
+                       local count,arg1,arg2,data = bin.unpack('LLH511',response,count)
+                       return data:sub(1,32)
+               else
+                       return nil, "Couldn't read block.." 
+               end
+       end
+       return nil, "No response from device"
+end
+
+local function main(args)
+
+       print( string.rep('--',20) )
+       print( string.rep('--',20) )
+       print()
+       
+       local keyA
+       local cmd
+       local err
+       local cmdReadBlockString = 'hf mf rdbl %d A %s'
+       
+       -- Arguments for the script
+       for o, a in getopt.getopt(args, 'hk:') do
+               if o == "h" then return help() end              
+               if o == "k" then keyA = a end
+       end
+
+       -- validate input args.
+       keyA =  keyA or '4b0b20107ccb'
+       if #(keyA) ~= 12 then
+               return oops( string.format('Wrong length of write key (was %d) expected 12', #keyA))
+       end
+       
+       result, err = lib14a.read1443a(false)
+       if not result then
+               print(err)
+               return
+       end
+       print((" Found tag : %s"):format(result.name))
+
+       core.clearCommandBuffer()
+       
+       if 0x01 ~= result.sak then -- NXP MIFARE TNP3xxx
+               print("This is not a TNP3xxx tag. aborting.")
+               return
+       end     
+       
+       -- Show info
+       print(('Using keyA : %s'):format(keyA))
+       print( string.rep('--',20) )
+
+       local cmdNestedString = 'hf mf nested 1 0 A %s d'
+       local cmdDumpString = 'hf mf dump'
+       --core.console(cmdNestedString.format(keyA) )
+       --core.console(cmdDumpString)
+
+       print('Reading data need to dump data')
+       
+       -- Read block 0
+       cmd = Command:new{cmd = cmds.CMD_MIFARE_READBL, arg1 = 0,arg2 = 0,arg3 = 0, data = keyA}
+       err = core.SendCommand(cmd:getBytes())
+       if err then return oops(err) end
+       local block0, err = waitCmd()
+       if err then return oops(err) end
+       
+       -- Read block 1
+       cmd = Command:new{cmd = cmds.CMD_MIFARE_READBL, arg1 = 1,arg2 = 0,arg3 = 0, data = keyA}
+       local err = core.SendCommand(cmd:getBytes())
+       if err then return oops(err) end
+       local block1, err = waitCmd()
+       if err then return oops(err) end
+
+
+       -- Read block 9
+       cmd = Command:new{cmd = cmds.CMD_MIFARE_READBL, arg1 = 9,arg2 = 0,arg3 = 0, data = '56f6313550f9'}
+       local err = core.SendCommand(cmd:getBytes())
+       if err then return oops(err) end
+       local block9, err = waitCmd()
+       if err then return oops(err) end
+       
+       -- main loop
+       print('BLOCK MD5                                 DECRYPTED                           ASCII' ) 
+               
+       for block=0,numBlocks-1,1 do
+       
+               if math.fmod(block,4) then
+                       
+               end
+               
+               local base = ('%s%s%02d%s'):format(block0, block1, block, hashconstant)
+               local md5hash = md5.sumhexa(base)
+               local aestest = core.aes(md5hash, block9 )
+               
+               local _,hex = bin.unpack(("H%d"):format(16),aestest)
+               
+               
+               local hexascii = string.gsub(hex, '(%x%x)', 
+                                                       function(value) 
+                                                               return string.char(tonumber(value, 16)) 
+                                                       end
+                                               )
+
+               print( block .. ' ::  ' .. md5hash .. ' :: ' .. hex .. ' :: ' .. hexascii  )    
+               
+               -- if core.ukbhit() then
+                       -- print("aborted by user")
+                       -- break
+               -- end
+       end
+end
+
+main(args)
\ No newline at end of file
index 5be13622336448edb7bea32d11239d1f7d8efdb6..2cdcbce3873b09ed6fea4f7bf6c4c5632f1c0b6e 100644 (file)
@@ -428,7 +428,7 @@ typedef struct _AT91S_PIO {
 #define PIO_PDR         (AT91_CAST(AT91_REG *)         0x00000004) // (PIO_PDR) PIO Disable Register
 #define PIO_PSR         (AT91_CAST(AT91_REG *)         0x00000008) // (PIO_PSR) PIO Status Register
 #define PIO_OER         (AT91_CAST(AT91_REG *)         0x00000010) // (PIO_OER) Output Enable Register
 #define PIO_PDR         (AT91_CAST(AT91_REG *)         0x00000004) // (PIO_PDR) PIO Disable Register
 #define PIO_PSR         (AT91_CAST(AT91_REG *)         0x00000008) // (PIO_PSR) PIO Status Register
 #define PIO_OER         (AT91_CAST(AT91_REG *)         0x00000010) // (PIO_OER) Output Enable Register
-#define PIO_ODR         (AT91_CAST(AT91_REG *)         0x00000014) // (PIO_ODR) Output Disable Registerr
+#define PIO_ODR         (AT91_CAST(AT91_REG *)         0x00000014) // (PIO_ODR) Output Disable Register
 #define PIO_OSR         (AT91_CAST(AT91_REG *)         0x00000018) // (PIO_OSR) Output Status Register
 #define PIO_IFER        (AT91_CAST(AT91_REG *)         0x00000020) // (PIO_IFER) Input Filter Enable Register
 #define PIO_IFDR        (AT91_CAST(AT91_REG *)         0x00000024) // (PIO_IFDR) Input Filter Disable Register
 #define PIO_OSR         (AT91_CAST(AT91_REG *)         0x00000018) // (PIO_OSR) Output Status Register
 #define PIO_IFER        (AT91_CAST(AT91_REG *)         0x00000020) // (PIO_IFER) Input Filter Enable Register
 #define PIO_IFDR        (AT91_CAST(AT91_REG *)         0x00000024) // (PIO_IFDR) Input Filter Disable Register
Impressum, Datenschutz