]> 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)) {
-                       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.
-                       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;
@@ -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)
 {
-       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
-       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
-       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);
-       cmd[11] = crc & 0xff;
-       cmd[12] = crc >> 8;
+       cmd[10] = crc & 0xff;
+       cmd[11] = crc >> 8;
 
        CodeIso15693AsReader(cmd, sizeof(cmd));
 }
@@ -1124,9 +1111,6 @@ void SimTagIso15693(uint32_t parameter, uint8_t *uid)
        
        memset(buf, 0x00, 100);
        
-       // Inventory response
-       BuildInventoryResponse(uid);
-       
        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.
+               
+               BuildInventoryResponse(uid);
+       
                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]);
 
+       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();
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
-       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;    
-       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.
-       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
@@ -479,12 +488,21 @@ void SimulateTagLowFrequency(int period, int gap, int ledcontrol)
                         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
@@ -492,18 +510,23 @@ void SimulateTagLowFrequency(int period, int gap, int ledcontrol)
                        }
                        WDT_HIT();
                 }
-        
+               
+               //SpinDelayUs(512);
+               
                ++i;
                if(i == period) {
                        i = 0;
                        if (gap) {
                                // turn of modulation
-                               SHORT_COIL();
+                               LOW(GPIO_SSC_DOUT);
                                // wait
                                SpinDelay(gap);
                        } 
                }
        }
+       DbpString("Stopped");
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+       return;
 }
 
 #define DEBUG_FRAME_CONTENTS 1
index b01b45ba02c582f9bc209f0a8feff1d3a7c936c8..1df3486d4b297cb15779eadee20a9618a5efad27 100644 (file)
@@ -21,6 +21,7 @@
 #include "cmdmain.h"
 #include "cmddata.h"
 
+
 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
-    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)) {
@@ -713,7 +716,7 @@ int CmdManchesterDemod(const char *Cmd)
       BitStream[i+14],
       BitStream[i+15]);
   }
-  return 0;
+  return bit2idx;
 }
 
 /* Modulate our data into manchester */
@@ -884,7 +887,7 @@ static command_t CommandTable[] =
 {
   {"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"},
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;
+               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;
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 */
-        i -= 9 + (5 * rows) -2;
+        i -= 9 + (5 * rows) -5;
 
         rows = header = 0;
       }
@@ -220,11 +220,11 @@ int CmdEM410xSim(const char *Cmd)
   int clock = 64;
 
   /* clear our graph */
-  ClearGraph(1);
+  ClearGraph(0);
   
   /* 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);
@@ -262,10 +262,10 @@ int CmdEM410xSim(const char *Cmd)
 
     /* stop bit */
     AppendGraph(0, clock, 0);
-  }
+  //}
 
   /* modulate that biatch */
-  CmdManchesterMod("64");
+  //CmdManchesterMod("64");
 
   /* booyah! */
   RepaintGraphWindow();
@@ -295,7 +295,7 @@ int CmdEM410xWatch(const char *Cmd)
                }
                
                CmdLFRead(read_h ? "h" : "");
-               CmdSamples("16000");
+               CmdSamples("6000");
                
        } while (
                !CmdEM410xRead("") 
@@ -654,8 +654,10 @@ int CmdWriteWordPWD(const char *Cmd)
 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"},
+  {"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"},
@@ -667,6 +669,265 @@ static command_t CommandTable[] =
   {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);
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 MWRem4xReplay(const char* Cmd);
 
 #endif
index 4e8cb89cc2f287d3577cf67acee5f23e20c07cee..7b45f3f2f1cf00d1df8bf1295fdb04d0dafd79b2 100644 (file)
@@ -89,6 +89,9 @@ int DetectClock(int peak)
                case 1: clock--; break;
                case 2: clock -= 2; break;
        }
+       if ( clock < 32) 
+               clock = 32;
+               
        printf("- adjusted it to %d \n", clock);
        return clock;
 }
index a52abdef7c41a530dc12dace4ff48b782c3a828f..b468eb2dbb3c01848040d9b7fadcbb61b97513e1 100644 (file)
@@ -55,6 +55,7 @@ local skel_1 = [[
                        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");
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', 
-  }
+       
+       --[[
+    Should be for Mifare TNP3xxx tags A KEY.
+    --]]
+       '4b0b20107ccb',
+
+}
 
 ---
 --    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"
+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"
index 963bb64c2b0dd616595671eb5923f5bc9c8e5049..fd065a044d7da49983dd57de781fa742e25a16bd 100644 (file)
@@ -18,6 +18,7 @@
 #include "util.h"
 #include "nonce2key/nonce2key.h"
 #include "../common/iso15693tools.h"
+#include <openssl/aes.h>   
 /**
  * The following params expected:
  *  UsbCommand c
@@ -224,6 +225,44 @@ static int l_iso15693_crc(lua_State *L)
     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.
@@ -259,8 +298,9 @@ int set_pm3_libraries(lua_State *L)
         {"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}
     };
 
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
+       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
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_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
Impressum, Datenschutz