]> git.zerfleddert.de Git - proxmark3-svn/commitdiff
Merge remote-tracking branch 'Proxmark/master' into iclass
authormarshmellow42 <marshmellowrf@gmail.com>
Wed, 7 Oct 2015 13:34:47 +0000 (09:34 -0400)
committermarshmellow42 <marshmellowrf@gmail.com>
Wed, 7 Oct 2015 13:34:47 +0000 (09:34 -0400)
Conflicts:
CHANGELOG.md

1  2 
CHANGELOG.md
armsrc/appmain.c
armsrc/apps.h
client/cmdhfmf.c
client/lualibs/commands.lua
client/util.h
include/usb_cmd.h

diff --combined CHANGELOG.md
index dffe9a81a464b107ac3fddf3b33ddac15a948f28,e2196a39afb8ed1c1d54fdf2311d4bb813cae4db..c5ccc8f751a1c28176dd7382c64c2966b9a861c0
@@@ -5,19 -5,16 +5,27 @@@ This project uses the changelog in acco
  ## [unreleased][unreleased]
  
  ### Added
 +- `hf iclass managekeys` to save, load and manage iclass keys.  (adjusted most commands to accept a loaded key in memory) (marshmellow)
 +- `hf iclass readblk` to select, authenticate, and read 1 block from an iclass card (marshmellow)
 +- `hf iclass writeblk` to select, authenticate, and write 1 block to an iclass card (or picopass) (marshmellow + others)
 +- `hf iclass clone` to take a saved dump file and clone selected blocks to a new tag (marshmellow + others)
 +- `hf iclass calcnewkey` - to calculate the div_key change to change a key - (experimental) (marshmellow + others)
 +- `hf iclass encryptblk` - to encrypt a data block hex to prep for writing that block (marshmellow)
  - ISO14443a stand-alone operation with ARM CFLAG="WITH_ISO14443a_StandAlone". This code can read & emulate two banks of 14a tag UIDs and write to "magic" cards  (Craig Young) 
  - AWID26 command context added as 'lf awid' containing realtime demodulation as well as cloning/simulation based on tag numbers (Craig Young)
+ - Added 'hw status'. This command makes the ARM print out some runtime information. (holiman) 
+ - Added 'hw ping'. This command just sends a usb packets and checks if the pm3 is responsive. Can be used to abort certain operations which supports abort over usb. (holiman)
+ - Added `data hex2bin` and `data bin2hex` for command line conversion between binary and hexadecimal (holiman)
  
  ### Changed
++<<<<<<< HEAD
 +- changed `lf config t <threshold>` to be 0 - 128 and will trigger on + or - threshold value (marshmellow) 
 +- `hf iclass dump` cli options - can now dump AA1 and AA2 with different keys in one run (does not go to muliple pages for the larger tags yet)
++=======
+ - Revised workflow for StandAloneMode14a (Craig Young)
++>>>>>>> Proxmark/master
  - EPA functions (`hf epa`) now support both ISO 14443-A and 14443-B cards (frederikmoellers)
+ - 'hw version' only talks to ARM at startup, after that the info is cached. (pwpiwi)
  
  ## [2.2.0][2015-07-12]
  
diff --combined armsrc/appmain.c
index 994bfa6c2ac5c22abea07cf267cb539d28d491eb,321782da8ee7af9f249dd392c220d0912ba03b90..48c9caef638975f3f4d22d338eb42918c090ffa0
@@@ -25,6 -25,7 +25,7 @@@
  #include <hitag2.h>
  #include "lfsampling.h"
  #include "BigBuf.h"
+ #include "mifareutil.h"
  #ifdef WITH_LCD
   #include "LCD.h"
  #endif
@@@ -298,6 -299,52 +299,52 @@@ void SendVersion(void
        cmd_send(CMD_ACK, *(AT91C_DBGU_CIDR), text_and_rodata_section_size + compressed_data_section_size, 0, VersionString, strlen(VersionString));
  }
  
+ // measure the USB Speed by sending SpeedTestBufferSize bytes to client and measuring the elapsed time.
+ // Note: this mimics GetFromBigbuf(), i.e. we have the overhead of the UsbCommand structure included.
+ void printUSBSpeed(void) 
+ {
+       Dbprintf("USB Speed:");
+       Dbprintf("  Sending USB packets to client...");
+       #define USB_SPEED_TEST_MIN_TIME 1500    // in milliseconds
+       uint8_t *test_data = BigBuf_get_addr();
+       uint32_t end_time;
+       uint32_t start_time = end_time = GetTickCount();
+       uint32_t bytes_transferred = 0;
+       
+       LED_B_ON();
+       while(end_time < start_time + USB_SPEED_TEST_MIN_TIME) {
+               cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K, 0, USB_CMD_DATA_SIZE, 0, test_data, USB_CMD_DATA_SIZE);
+               end_time = GetTickCount();
+               bytes_transferred += USB_CMD_DATA_SIZE;
+       }
+       LED_B_OFF();
+       Dbprintf("  Time elapsed:      %dms", end_time - start_time);
+       Dbprintf("  Bytes transferred: %d", bytes_transferred);
+       Dbprintf("  USB Transfer Speed PM3 -> Client = %d Bytes/s", 
+               1000 * bytes_transferred / (end_time - start_time));
+ }
+       
+ /**
+   * Prints runtime information about the PM3.
+ **/
+ void SendStatus(void)
+ {
+       BigBuf_print_status();
+       Fpga_print_status();
+       printConfig(); //LF Sampling config
+       printUSBSpeed();
+       Dbprintf("Various");
+       Dbprintf("  MF_DBGLEVEL......%d", MF_DBGLEVEL);
+       Dbprintf("  ToSendMax........%d",ToSendMax);
+       Dbprintf("  ToSendBit........%d",ToSendBit);
+       cmd_send(CMD_ACK,1,0,0,0,0);
+ }
  #if defined(WITH_ISO14443a_StandAlone) || defined(WITH_LF)
  
  #define OPTS 2
@@@ -329,11 -376,14 +376,14 @@@ void StandAloneMode14a(
        FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
  
        int selected = 0;
-       int playing = 0;
+       int playing = 0, iGotoRecord = 0, iGotoClone = 0;
        int cardRead[OPTS] = {0};
        uint8_t readUID[10] = {0};
        uint32_t uid_1st[OPTS]={0};
        uint32_t uid_2nd[OPTS]={0};
+       uint32_t uid_tmp1 = 0;
+       uint32_t uid_tmp2 = 0;
+       iso14a_card_select_t hi14a_card[OPTS];
  
        LED(selected + 1, 0);
  
        {
                usb_poll();
                WDT_HIT();
-               // Was our button held down or pressed?
-               int button_pressed = BUTTON_HELD(1000);
                SpinDelay(300);
  
-               // Button was held for a second, begin recording
-               if (button_pressed > 0 && cardRead[selected] == 0)
+               if (iGotoRecord == 1 || cardRead[selected] == 0)
                {
+                       iGotoRecord = 0;
                        LEDsoff();
                        LED(selected + 1, 0);
                        LED(LED_RED2, 0);
  
                        // record
                        Dbprintf("Enabling iso14443a reader mode for [Bank: %u]...", selected);
-                       // wait for button to be released
-                       while(BUTTON_PRESS())
-                               WDT_HIT();
                        /* need this delay to prevent catching some weird data */
                        SpinDelay(500);
                        /* Code for reading from 14a tag */
                        for ( ; ; )
                        {
                                WDT_HIT();
-                               if (!iso14443a_select_card(uid, NULL, &cuid))
+                               if (BUTTON_PRESS()) {
+                                       if (cardRead[selected]) {
+                                               Dbprintf("Button press detected -- replaying card in bank[%d]", selected);
+                                               break;
+                                       }
+                                       else if (cardRead[(selected+1)%OPTS]) {
+                                               Dbprintf("Button press detected but no card in bank[%d] so playing from bank[%d]", selected, (selected+1)%OPTS);
+                                               selected = (selected+1)%OPTS;
+                                               break; // playing = 1;
+                                       }
+                                       else {
+                                               Dbprintf("Button press detected but no stored tag to play. (Ignoring button)");
+                                               SpinDelay(300);
+                                       }
+                               }
+                               if (!iso14443a_select_card(uid, &hi14a_card[selected], &cuid))
                                        continue;
                                else
                                {
                                        Dbprintf("Read UID:"); Dbhexdump(10,uid,0);
                                        memcpy(readUID,uid,10*sizeof(uint8_t));
-                                       uint8_t *dst = (uint8_t *)&uid_1st[selected];
+                                       uint8_t *dst = (uint8_t *)&uid_tmp1;
                                        // Set UID byte order
                                        for (int i=0; i<4; i++)
                                                dst[i] = uid[3-i];
-                                       dst = (uint8_t *)&uid_2nd[selected];
+                                       dst = (uint8_t *)&uid_tmp2;
                                        for (int i=0; i<4; i++)
                                                dst[i] = uid[7-i];
-                                       break;
+                                       if (uid_1st[(selected+1)%OPTS] == uid_tmp1 && uid_2nd[(selected+1)%OPTS] == uid_tmp2) {
+                                               Dbprintf("Card selected has same UID as what is stored in the other bank. Skipping.");
+                                       }
+                                       else {
+                                               if (uid_tmp2) {
+                                                       Dbprintf("Bank[%d] received a 7-byte UID",selected);
+                                                       uid_1st[selected] = (uid_tmp1)>>8;
+                                                       uid_2nd[selected] = (uid_tmp1<<24) + (uid_tmp2>>8);
+                                               }
+                                               else {
+                                                       Dbprintf("Bank[%d] received a 4-byte UID",selected);
+                                                       uid_1st[selected] = uid_tmp1;
+                                                       uid_2nd[selected] = uid_tmp2;
+                                               }
+                                               break;
+                                       }
                                }
                        }
+                       Dbprintf("ATQA = %02X%02X",hi14a_card[selected].atqa[0],hi14a_card[selected].atqa[1]);
+                       Dbprintf("SAK = %02X",hi14a_card[selected].sak);
                        LEDsoff();
                        LED(LED_GREEN,  200);
                        LED(LED_ORANGE, 200);
  
                        LEDsoff();
                        LED(selected + 1, 0);
-                       // Finished recording
  
-                       // If we were previously playing, set playing off
-                       // so next button push begins playing what we recorded
-                       playing = 0;
+                       // Next state is replay:
+                       playing = 1;
  
                        cardRead[selected] = 1;
                }
-               /* MF UID clone */
-               else if (button_pressed > 0 && cardRead[selected] == 1)
+               /* MF Classic UID clone */
+               else if (iGotoClone==1)
                {
-                                       LEDsoff();
-                                       LED(selected + 1, 0);
-                                       LED(LED_ORANGE, 250);
+                       iGotoClone=0;
+                       LEDsoff();
+                       LED(selected + 1, 0);
+                       LED(LED_ORANGE, 250);
  
-                                       // record
-                                       Dbprintf("Preparing to Clone card [Bank: %x]; uid: %08x", selected, uid_1st[selected]);
  
-                                       // wait for button to be released
-                                       while(BUTTON_PRESS())
-                                       {
-                                               // Delay cloning until card is in place
-                                               WDT_HIT();
-                                       }
-                                       Dbprintf("Starting clone. [Bank: %u]", selected);
-                                       // need this delay to prevent catching some weird data
-                                       SpinDelay(500);
-                                       // Begin clone function here:
-                                       /* Example from client/mifarehost.c for commanding a block write for "magic Chinese" cards:
-                                                       UsbCommand c = {CMD_MIFARE_CSETBLOCK, {wantWipe, params & (0xFE | (uid == NULL ? 0:1)), blockNo}};
-                                                       memcpy(c.d.asBytes, data, 16);
-                                                       SendCommand(&c);
-                                               Block read is similar:
-                                                       UsbCommand c = {CMD_MIFARE_CGETBLOCK, {params, 0, blockNo}};
-                                               We need to imitate that call with blockNo 0 to set a uid.
-                                               The get and set commands are handled in this file:
-                                                       // Work with "magic Chinese" card
-                                                       case CMD_MIFARE_CSETBLOCK:
-                                                                       MifareCSetBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
-                                                                       break;
-                                                       case CMD_MIFARE_CGETBLOCK:
-                                                                       MifareCGetBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
-                                                                                                       //
-                                                                       break;
-                                               mfCSetUID provides example logic for UID set workflow:
-                                                       -Read block0 from card in field with MifareCGetBlock()
-                                                       -Configure new values without replacing reserved bytes
-                                                                       memcpy(block0, uid, 4); // Copy UID bytes from byte array
-                                                                       // Mifare UID BCC
-                                                                       block0[4] = block0[0]^block0[1]^block0[2]^block0[3]; // BCC on byte 5
-                                                                       Bytes 5-7 are reserved SAK and ATQA for mifare classic
-                                                       -Use mfCSetBlock(0, block0, oldUID, wantWipe, CSETBLOCK_SINGLE_OPER) to write it
-                                       */
-                                       uint8_t oldBlock0[16] = {0}, newBlock0[16] = {0}, testBlock0[16] = {0};
-                                       // arg0 = Flags == CSETBLOCK_SINGLE_OPER=0x1F, arg1=returnSlot, arg2=blockNo
-                                       MifareCGetBlock(0x1F, 1, 0, oldBlock0);
-                                       Dbprintf("UID from target tag: %02X%02X%02X%02X", oldBlock0[0],oldBlock0[1],oldBlock0[2],oldBlock0[3]);
-                                       memcpy(newBlock0,oldBlock0,16);
-                                       // Copy uid_1st for bank (2nd is for longer UIDs not supported if classic)
-                                       newBlock0[0] = uid_1st[selected]>>24;
-                                       newBlock0[1] = 0xFF & (uid_1st[selected]>>16);
-                                       newBlock0[2] = 0xFF & (uid_1st[selected]>>8);
-                                       newBlock0[3] = 0xFF & (uid_1st[selected]);
-                                       newBlock0[4] = newBlock0[0]^newBlock0[1]^newBlock0[2]^newBlock0[3];
-                                       // arg0 = needWipe, arg1 = workFlags, arg2 = blockNo, datain
-                                       MifareCSetBlock(0, 0xFF,0, newBlock0);
-                                       MifareCGetBlock(0x1F, 1, 0, testBlock0);
-                                       if (memcmp(testBlock0,newBlock0,16)==0)
-                                       {
-                                               DbpString("Cloned successfull!");
-                                               cardRead[selected] = 0; // Only if the card was cloned successfully should we clear it
-                                       }
-                                       LEDsoff();
-                                       LED(selected + 1, 0);
-                                       // Finished recording
+                       // record
+                       Dbprintf("Preparing to Clone card [Bank: %x]; uid: %08x", selected, uid_1st[selected]);
  
-                                       // If we were previously playing, set playing off
-                                       // so next button push begins playing what we recorded
+                       // wait for button to be released
+                       while(BUTTON_PRESS())
+                       {
+                               // Delay cloning until card is in place
+                               WDT_HIT();
+                       }
+                       Dbprintf("Starting clone. [Bank: %u]", selected);
+                       // need this delay to prevent catching some weird data
+                       SpinDelay(500);
+                       // Begin clone function here:
+                       /* Example from client/mifarehost.c for commanding a block write for "magic Chinese" cards:
+                                       UsbCommand c = {CMD_MIFARE_CSETBLOCK, {wantWipe, params & (0xFE | (uid == NULL ? 0:1)), blockNo}};
+                                       memcpy(c.d.asBytes, data, 16);
+                                       SendCommand(&c);
+                                       Block read is similar:
+                                       UsbCommand c = {CMD_MIFARE_CGETBLOCK, {params, 0, blockNo}};
+                                       We need to imitate that call with blockNo 0 to set a uid.
+                                       The get and set commands are handled in this file:
+                                       // Work with "magic Chinese" card
+                                       case CMD_MIFARE_CSETBLOCK:
+                                               MifareCSetBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
+                                               break;
+                                       case CMD_MIFARE_CGETBLOCK:
+                                               MifareCGetBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
+                                               break;
+                               mfCSetUID provides example logic for UID set workflow:
+                                       -Read block0 from card in field with MifareCGetBlock()
+                                       -Configure new values without replacing reserved bytes
+                                                       memcpy(block0, uid, 4); // Copy UID bytes from byte array
+                                                       // Mifare UID BCC
+                                                       block0[4] = block0[0]^block0[1]^block0[2]^block0[3]; // BCC on byte 5
+                                                       Bytes 5-7 are reserved SAK and ATQA for mifare classic
+                                       -Use mfCSetBlock(0, block0, oldUID, wantWipe, CSETBLOCK_SINGLE_OPER) to write it
+                       */
+                       uint8_t oldBlock0[16] = {0}, newBlock0[16] = {0}, testBlock0[16] = {0};
+                       // arg0 = Flags == CSETBLOCK_SINGLE_OPER=0x1F, arg1=returnSlot, arg2=blockNo
+                       MifareCGetBlock(0x3F, 1, 0, oldBlock0);
+                       if (oldBlock0[0] == 0 && oldBlock0[0] == oldBlock0[1]  && oldBlock0[1] == oldBlock0[2] && oldBlock0[2] == oldBlock0[3]) {
+                               Dbprintf("No changeable tag detected. Returning to replay mode for bank[%d]", selected);
+                               playing = 1;
+                       }
+                       else {
+                               Dbprintf("UID from target tag: %02X%02X%02X%02X", oldBlock0[0],oldBlock0[1],oldBlock0[2],oldBlock0[3]);
+                               memcpy(newBlock0,oldBlock0,16);
+                               // Copy uid_1st for bank (2nd is for longer UIDs not supported if classic)
+                               newBlock0[0] = uid_1st[selected]>>24;
+                               newBlock0[1] = 0xFF & (uid_1st[selected]>>16);
+                               newBlock0[2] = 0xFF & (uid_1st[selected]>>8);
+                               newBlock0[3] = 0xFF & (uid_1st[selected]);
+                               newBlock0[4] = newBlock0[0]^newBlock0[1]^newBlock0[2]^newBlock0[3];
+                               // arg0 = needWipe, arg1 = workFlags, arg2 = blockNo, datain
+                               MifareCSetBlock(0, 0xFF,0, newBlock0);
+                               MifareCGetBlock(0x3F, 1, 0, testBlock0);
+                               if (memcmp(testBlock0,newBlock0,16)==0)
+                               {
+                                       DbpString("Cloned successfull!");
+                                       cardRead[selected] = 0; // Only if the card was cloned successfully should we clear it
                                        playing = 0;
+                                       iGotoRecord = 1;
+                                       selected = (selected+1) % OPTS;
+                               }
+                               else {
+                                       Dbprintf("Clone failed. Back to replay mode on bank[%d]", selected);
+                                       playing = 1;
+                               }
+                       }
+                       LEDsoff();
+                       LED(selected + 1, 0);
  
                }
                // Change where to record (or begin playing)
-               else if (button_pressed && cardRead[selected])
+               else if (playing==1) // button_pressed == BUTTON_SINGLE_CLICK && cardRead[selected])
                {
-                       // Next option if we were previously playing
-                       if (playing)
-                               selected = (selected + 1) % OPTS;
-                       playing = !playing;
                        LEDsoff();
                        LED(selected + 1, 0);
  
                        {
                                LED(LED_GREEN, 0);
                                DbpString("Playing");
-                               while (!BUTTON_HELD(500)) { // Loop simulating tag until the button is held a half-sec
+                               for ( ; ; ) {
+                                       WDT_HIT();
+                                       int button_action = BUTTON_HELD(1000);
+                                       if (button_action == 0) { // No button action, proceed with sim
+                                               uint8_t data[512] = {0}; // in case there is a read command received we shouldn't break
                                                Dbprintf("Simulating ISO14443a tag with uid[0]: %08x, uid[1]: %08x [Bank: %u]", uid_1st[selected],uid_2nd[selected],selected);
-                                               SimulateIso14443aTag(1,uid_1st[selected],uid_2nd[selected],NULL);
+                                               if (hi14a_card[selected].sak == 8 && hi14a_card[selected].atqa[0] == 4 && hi14a_card[selected].atqa[1] == 0) {
+                                                       DbpString("Mifare Classic");
+                                                       SimulateIso14443aTag(1,uid_1st[selected], uid_2nd[selected], data); // Mifare Classic
+                                               }
+                                               else if (hi14a_card[selected].sak == 0 && hi14a_card[selected].atqa[0] == 0x44 && hi14a_card[selected].atqa[1] == 0) {
+                                                       DbpString("Mifare Ultralight");
+                                                       SimulateIso14443aTag(2,uid_1st[selected],uid_2nd[selected],data); // Mifare Ultralight
+                                               }
+                                               else if (hi14a_card[selected].sak == 20 && hi14a_card[selected].atqa[0] == 0x44 && hi14a_card[selected].atqa[1] == 3) {
+                                                       DbpString("Mifare DESFire");
+                                                       SimulateIso14443aTag(3,uid_1st[selected],uid_2nd[selected],data); // Mifare DESFire
+                                               }
+                                               else {
+                                                       Dbprintf("Unrecognized tag type -- defaulting to Mifare Classic emulation");
+                                                       SimulateIso14443aTag(1,uid_1st[selected], uid_2nd[selected], data);
+                                               }
+                                       }
+                                       else if (button_action == BUTTON_SINGLE_CLICK) {
+                                               selected = (selected + 1) % OPTS;
+                                               Dbprintf("Done playing. Switching to record mode on bank %d",selected);
+                                               iGotoRecord = 1;
+                                               break;
                                        }
-                               //cardRead[selected] = 1;
-                               Dbprintf("Done playing [Bank: %u]",selected);
+                                       else if (button_action == BUTTON_HOLD) {
+                                               Dbprintf("Playtime over. Begin cloning...");
+                                               iGotoClone = 1;
+                                               break;
+                                       }
+                                       WDT_HIT();
+                               }
  
                                /* We pressed a button so ignore it here with a delay */
                                SpinDelay(300);
-                               // when done, we're done playing, move to next option
-                               selected = (selected + 1) % OPTS;
-                               playing = !playing;
                                LEDsoff();
                                LED(selected + 1, 0);
                        }
@@@ -886,6 -987,9 +987,9 @@@ void UsbPacketReceived(uint8_t *packet
                        ReadPCF7931();
                        cmd_send(CMD_ACK,0,0,0,0,0);
                        break;
+               case CMD_PCF7931_WRITE:
+                       WritePCF7931(c->d.asDwords[0],c->d.asDwords[1],c->d.asDwords[2],c->d.asDwords[3],c->d.asDwords[4],c->d.asDwords[5],c->d.asDwords[6], c->d.asDwords[9], c->d.asDwords[7]-128,c->d.asDwords[8]-128, c->arg[0], c->arg[1], c->arg[2]);
+                       break;
                case CMD_EM4X_READ_WORD:
                        EM4xReadWord(c->arg[1], c->arg[2],c->d.asBytes[0]);
                        break;
                        ReaderIClass(c->arg[0]);
                        break;
                case CMD_READER_ICLASS_REPLAY:
 -                  ReaderIClass_Replay(c->arg[0], c->d.asBytes);
 +                      ReaderIClass_Replay(c->arg[0], c->d.asBytes);
                        break;
 -      case CMD_ICLASS_EML_MEMSET:
 +              case CMD_ICLASS_EML_MEMSET:
                        emlSet(c->d.asBytes,c->arg[0], c->arg[1]);
                        break;
 +              case CMD_ICLASS_WRITEBLOCK:
 +                      iClass_WriteBlock(c->arg[0], c->d.asBytes);
 +                      break;
 +              case CMD_ICLASS_READCHECK:  // auth step 1
 +                      iClass_ReadCheck(c->arg[0], c->arg[1]);
 +                      break;
 +              case CMD_ICLASS_READBLOCK:
 +                      iClass_ReadBlk(c->arg[0]);
 +                      break;
 +              case CMD_ICLASS_AUTHENTICATION: //check
 +                      iClass_Authentication(c->d.asBytes);
 +                      break;
 +              case CMD_ICLASS_DUMP:
 +                      iClass_Dump(c->arg[0], c->arg[1]);
 +                      break;
 +              case CMD_ICLASS_CLONE:
 +                      iClass_Clone(c->arg[0], c->arg[1], c->d.asBytes);
 +                      break;
  #endif
  
                case CMD_BUFF_CLEAR:
                case CMD_VERSION:
                        SendVersion();
                        break;
+               case CMD_STATUS:
+                       SendStatus();
+                       break;
+               case CMD_PING:
+                       cmd_send(CMD_ACK,0,0,0,0,0);
+                       break;
  #ifdef WITH_LCD
                case CMD_LCD_RESET:
                        LCDReset();
diff --combined armsrc/apps.h
index 63b2edc5f2ba377113cdb9335a22be2c427dcdd0,d5c8ba0ae888112365bfd7888645989fb6e24d5f..79c9da8620b9b1db2996a6c26abbf2c211948df2
@@@ -61,6 -61,7 +61,7 @@@ void AcquireRawAdcSamples125k(int divis
  void ModThenAcquireRawAdcSamples125k(int delay_off,int period_0,int period_1,uint8_t *command);
  void ReadTItag(void);
  void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc);
  void AcquireTiType(void);
  void AcquireRawBitsTI(void);
  void SimulateTagLowFrequency(int period, int gap, int ledcontrol);
@@@ -85,6 -86,11 +86,11 @@@ int DemodPCF7931(uint8_t **outBlocks)
  int IsBlock0PCF7931(uint8_t *Block);
  int IsBlock1PCF7931(uint8_t *Block);
  void ReadPCF7931();
+ void SendCmdPCF7931(uint32_t * tab);
+ bool AddBytePCF7931(uint8_t byte, uint32_t * tab, int32_t l, int32_t p);
+ bool AddBitPCF7931(bool b, uint32_t * tab, int32_t l, int32_t p);
+ bool AddPatternPCF7931(uint32_t a, uint32_t b, uint32_t c, uint32_t * tab);
+ void WritePCF7931(uint8_t pass1, uint8_t pass2, uint8_t pass3, uint8_t pass4, uint8_t pass5, uint8_t pass6, uint8_t pass7, uint16_t init_delay, int32_t l, int32_t p, uint8_t address, uint8_t byte, uint8_t data);
  void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode);
  void EM4xWriteWord(uint32_t Data, uint8_t Address, uint32_t Pwd, uint8_t PwdMode);
  
@@@ -150,6 -156,9 +156,6 @@@ void       OnSuccess()
  void  OnError(uint8_t reason);
  
  
 -
 -
 -
  /// iso15693.h
  void RecordRawAdcSamplesIso15693(void);
  void AcquireRawAdcSamplesIso15693(void);
@@@ -165,13 -174,6 +171,13 @@@ void SimulateIClass(uint32_t arg0, uint
  void ReaderIClass(uint8_t arg0);
  void ReaderIClass_Replay(uint8_t arg0,uint8_t *MAC);
  void IClass_iso14443A_GetPublic(uint8_t arg0);
 +void iClass_Authentication(uint8_t *MAC);
 +void iClass_WriteBlock(uint8_t blockNo, uint8_t *data);
 +void iClass_ReadBlk(uint8_t blockNo);
 +bool iClass_ReadBlock(uint8_t blockNo, uint8_t *readdata);
 +void iClass_Dump(uint8_t blockno, uint8_t numblks);
 +void iClass_Clone(uint8_t startblock, uint8_t endblock, uint8_t *data);
 +void iClass_ReadCheck(uint8_t blockNo, uint8_t keyType);
  
  // hitag2.h
  void SnoopHitag(uint32_t type);
diff --combined client/cmdhfmf.c
index c4a0aeebd615a60eb978942d5db30930798a4171,8a8a38fcaf19961b9ea059318acaa261dd2e7c5c..304e9c9c3b0d870e09f2f2096bec6785a7be50b3
@@@ -58,6 -58,7 +58,7 @@@ start
                                case -1 : PrintAndLog("Button pressed. Aborted.\n"); break;\r
                                case -2 : PrintAndLog("Card is not vulnerable to Darkside attack (doesn't send NACK on authentication requests).\n"); break;\r
                                case -3 : PrintAndLog("Card is not vulnerable to Darkside attack (its random number generator is not predictable).\n"); break;\r
+                               case -4 : PrintAndLog("The card's random number generator is vulnerable but behaves somewhat weird (Mifare clone?). This needs to be fixed.\n"); break;\r
                                default: ;\r
                        }\r
                        break;\r
@@@ -1949,13 -1950,6 +1950,13 @@@ int CmdHF14AMfSniff(const char *Cmd)
        return 0;\r
  }\r
  \r
 +//needs nt, ar, at, Data to decrypt\r
 +int CmdDecryptTraceCmds(const char *Cmd){\r
 +      uint8_t data[50];\r
 +      int len = 0;\r
 +      param_gethex_ex(Cmd,3,data,&len);\r
 +      return tryDecryptWord(param_get32ex(Cmd,0,0,16),param_get32ex(Cmd,1,0,16),param_get32ex(Cmd,2,0,16),data,len/2);\r
 +}\r
  \r
  static command_t CommandTable[] =\r
  {\r
    {"cgetsc",  CmdHF14AMfCGetSc,               0, "Read sector - Magic Chinese card"},\r
    {"cload",           CmdHF14AMfCLoad,                0, "Load dump into magic Chinese card"},\r
    {"csave",           CmdHF14AMfCSave,                0, "Save dump from magic Chinese card into file or emulator"},\r
 +  {"decrypt", CmdDecryptTraceCmds,1, "[nt] [ar_enc] [at_enc] [data] - to decrypt snoop or trace"},\r
    {NULL, NULL, 0, NULL}\r
  };\r
  \r
index 4e98bd28db1854b53eaa06930c47eae527a14e85,64f16e4491ab95769e358b9f685d727242ef789c..5f34976fa41141748d41f531435ae45460f98f13
@@@ -20,7 -20,8 +20,8 @@@ local _commands = 
        CMD_BUFF_CLEAR =                                                     0x0105,
        CMD_READ_MEM =                                                       0x0106,
        CMD_VERSION =                                                        0x0107,
+       CMD_STATUS =                                                         0x0108,
+       CMD_PING =                                                           0x0109,
        --// For low-frequency tags
        CMD_READ_TI_TYPE =                                                   0x0202,
        CMD_WRITE_TI_TYPE =                                                  0x0203,
        CMD_EPA_PACE_COLLECT_NONCE =                                         0x038A,
        --//CMD_EPA_ =                                                         0x038B,
  
 +      CMD_ICLASS_READCHECK =                                               0x038F,
 +      CMD_ICLASS_CLONE =                                                   0x0390,
 +      CMD_ICLASS_DUMP =                                                    0x0391,
        CMD_SNOOP_ICLASS =                                                   0x0392,
        CMD_SIMULATE_TAG_ICLASS =                                            0x0393,
        CMD_READER_ICLASS =                                                  0x0394,
 -      CMD_READER_ICLASS_REPLAY =                                                                                       0x0395,
 -      CMD_ICLASS_ISO14443A_WRITE =                                                                             0x0397,
 +      CMD_READER_ICLASS_REPLAY =                                           0x0395,
 +      CMD_ICLASS_READBLOCK =                                               0x0396,
 +      CMD_ICLASS_WRITEBLOCK =                                              0x0397,
 +      CMD_ICLASS_EML_MEMSET =                                              0x0398,
 +      CMD_ICLASS_AUTHENTICATION =                                          0x0399,
  
        --// For measurements of the antenna tuning
        CMD_MEASURE_ANTENNA_TUNING =                                         0x0400,
diff --combined client/util.h
index 19c346044eab61e4b4890d9e51fb83aef41d6d1a,94021c2c78fe3c409c428a0e6fb4e3410a4c680c..8bf4f3881c28c624f13ec8026f0e0a03680791e5
@@@ -47,6 -47,7 +47,7 @@@ char * printBits(size_t const size, voi
  uint8_t *SwapEndian64(const uint8_t *src, const size_t len, const uint8_t blockSize);
  
  char param_getchar(const char *line, int paramnum);
+ int param_getptr(const char *line, int *bg, int *en, int paramnum);
  uint8_t param_get8(const char *line, int paramnum);
  uint8_t param_get8ex(const char *line, int paramnum, int deflt, int base);
  uint32_t param_get32ex(const char *line, int paramnum, int deflt, int base);
@@@ -54,7 -55,6 +55,7 @@@ uint64_t param_get64ex(const char *line
  uint8_t param_getdec(const char *line, int paramnum, uint8_t *destination);
  uint8_t param_isdec(const char *line, int paramnum);
  int param_gethex(const char *line, int paramnum, uint8_t * data, int hexcnt);
 +int param_gethex_ex(const char *line, int paramnum, uint8_t * data, int *hexcnt);
  int param_getstr(const char *line, int paramnum, char * str);
  
   int hextobinarray( char *target,  char *source);
diff --combined include/usb_cmd.h
index 3afed7c3ff77ae598500608db0274fe41babb56d,a58feb383499e4cb85d4dffa7eef654ea432e6cf..0f649a69ab40490f7b95703cceba2cac02bc964c
@@@ -60,6 -60,8 +60,8 @@@ typedef struct
  #define CMD_BUFF_CLEAR                                                    0x0105
  #define CMD_READ_MEM                                                      0x0106
  #define CMD_VERSION                                                       0x0107
+ #define CMD_STATUS                                                                                                              0x0108
+ #define CMD_PING                                                                                                                0x0109
  
  // For low-frequency tags
  #define CMD_READ_TI_TYPE                                                  0x0202
@@@ -85,6 -87,7 +87,7 @@@
  #define CMD_T55XX_WRITE_BLOCK                                             0x0215
  #define CMD_T55XX_READ_TRACE                                              0x0216
  #define CMD_PCF7931_READ                                                  0x0217
+ #define CMD_PCF7931_WRITE                                                 0x0222
  #define CMD_EM4X_READ_WORD                                                0x0218
  #define CMD_EM4X_WRITE_WORD                                               0x0219
  #define CMD_IO_DEMOD_FSK                                                  0x021A
  #define CMD_PSK_SIM_TAG                                                   0x0220
  #define CMD_AWID_DEMOD_FSK                                                0x0221
  
  /* CMD_SET_ADC_MUX: ext1 is 0 for lopkd, 1 for loraw, 2 for hipkd, 3 for hiraw */
  
  // For the 13.56 MHz tags
  #define CMD_EPA_PACE_COLLECT_NONCE                                        0x038A
  #define CMD_EPA_PACE_REPLAY                                               0x038B
  
 +#define CMD_ICLASS_READCHECK                                              0x038F
 +#define CMD_ICLASS_CLONE                                                  0x0390
 +#define CMD_ICLASS_DUMP                                                   0x0391
  #define CMD_SNOOP_ICLASS                                                  0x0392
  #define CMD_SIMULATE_TAG_ICLASS                                           0x0393
  #define CMD_READER_ICLASS                                                 0x0394
  #define CMD_READER_ICLASS_REPLAY                                          0x0395
 -#define CMD_ICLASS_ISO14443A_WRITE                                        0x0397
 +#define CMD_ICLASS_READBLOCK                                              0x0396
 +#define CMD_ICLASS_WRITEBLOCK                                             0x0397
  #define CMD_ICLASS_EML_MEMSET                                             0x0398
 +#define CMD_ICLASS_AUTHENTICATION                                         0x0399
  
  // For measurements of the antenna tuning
  #define CMD_MEASURE_ANTENNA_TUNING                                        0x0400
  #define FLAG_ICLASS_READER_CONF         0x08
  #define FLAG_ICLASS_READER_AA           0x10
  #define FLAG_ICLASS_READER_ONE_TRY      0x20
 +#define FLAG_ICLASS_READER_CEDITKEY     0x40
  
  
  
Impressum, Datenschutz