]> cvs.zerfleddert.de Git - proxmark3-svn/blobdiff - armsrc/appmain.c
Remove unused functions le32toh, le24toh, hextobinstring, binarraytobinstring, print_...
[proxmark3-svn] / armsrc / appmain.c
index 4c475541b41ba28e572533b0c7f3121575316091..f7bcd620348a0b5e90fc0ab1f3f19699d5cd2236 100644 (file)
 #include "cmd.h"
 #include "proxmark3.h"
 #include "apps.h"
+#include "fpga.h"
 #include "util.h"
 #include "printf.h"
 #include "string.h"
 #include "legicrf.h"
+#include "legicrfsim.h"
 #include "hitag2.h"
 #include "hitagS.h"
 #include "lfsampling.h"
 #ifdef WITH_LCD
  #include "LCD.h"
 #endif
+#ifdef WITH_SMARTCARD
+ #include "i2c.h"
+#endif
+
 
 // Craig Young - 14a stand-alone code
-#ifdef WITH_ISO14443a_StandAlone
+#ifdef WITH_ISO14443a
  #include "iso14443a.h"
 #endif
 
@@ -135,35 +141,28 @@ void Dbhexdump(int len, uint8_t *d, bool bAsci) {
 // return that.
 //-----------------------------------------------------------------------------
 static int ReadAdc(int ch)
-{
-       uint32_t d;
-
-       AT91C_BASE_ADC->ADC_CR = AT91C_ADC_SWRST;
-       AT91C_BASE_ADC->ADC_MR =
-               ADC_MODE_PRESCALE(63  /* was 32 */) |                                                   // ADC_CLK = MCK / ((63+1) * 2) = 48MHz / 128 = 375kHz
-               ADC_MODE_STARTUP_TIME(1  /* was 16 */) |                                                // Startup Time = (1+1) * 8 / ADC_CLK = 16 / 375kHz = 42,7us     Note: must be > 20us
-               ADC_MODE_SAMPLE_HOLD_TIME(15  /* was 8 */);                                     // Sample & Hold Time SHTIM = 15 / ADC_CLK = 15 / 375kHz = 40us
-
+{      
        // Note: ADC_MODE_PRESCALE and ADC_MODE_SAMPLE_HOLD_TIME are set to the maximum allowed value. 
-       // Both AMPL_LO and AMPL_HI are very high impedance (10MOhm) outputs, the input capacitance of the ADC is 12pF (typical). This results in a time constant
-       // of RC = 10MOhm * 12pF = 120us. Even after the maximum configurable sample&hold time of 40us the input capacitor will not be fully charged. 
+       // AMPL_HI is are high impedance (10MOhm || 1MOhm) output, the input capacitance of the ADC is 12pF (typical). This results in a time constant
+       // of RC = (0.91MOhm) * 12pF = 10.9us. Even after the maximum configurable sample&hold time of 40us the input capacitor will not be fully charged. 
        // 
        // The maths are:
        // If there is a voltage v_in at the input, the voltage v_cap at the capacitor (this is what we are measuring) will be
        //
-       //       v_cap = v_in * (1 - exp(-RC/SHTIM))  =   v_in * (1 - exp(-3))  =  v_in * 0,95                   (i.e. an error of 5%)
-       // 
-       // Note: with the "historic" values in the comments above, the error was 34%  !!!
-       
-       AT91C_BASE_ADC->ADC_CHER = ADC_CHANNEL(ch);
+       //       v_cap = v_in * (1 - exp(-SHTIM/RC))  =   v_in * (1 - exp(-40us/10.9us))  =  v_in * 0,97                   (i.e. an error of 3%)
 
-       AT91C_BASE_ADC->ADC_CR = AT91C_ADC_START;
+       AT91C_BASE_ADC->ADC_CR = AT91C_ADC_SWRST;
+       AT91C_BASE_ADC->ADC_MR =
+               ADC_MODE_PRESCALE(63) |                                                 // ADC_CLK = MCK / ((63+1) * 2) = 48MHz / 128 = 375kHz
+               ADC_MODE_STARTUP_TIME(1) |                                              // Startup Time = (1+1) * 8 / ADC_CLK = 16 / 375kHz = 42,7us     Note: must be > 20us
+               ADC_MODE_SAMPLE_HOLD_TIME(15);                                  // Sample & Hold Time SHTIM = 15 / ADC_CLK = 15 / 375kHz = 40us
 
-       while(!(AT91C_BASE_ADC->ADC_SR & ADC_END_OF_CONVERSION(ch)))
-               ;
-       d = AT91C_BASE_ADC->ADC_CDR[ch];
+       AT91C_BASE_ADC->ADC_CHER = ADC_CHANNEL(ch);
+       AT91C_BASE_ADC->ADC_CR = AT91C_ADC_START;
 
-       return d;
+       while(!(AT91C_BASE_ADC->ADC_SR & ADC_END_OF_CONVERSION(ch))) {};
+       
+       return AT91C_BASE_ADC->ADC_CDR[ch];
 }
 
 int AvgAdc(int ch) // was static - merlok
@@ -193,6 +192,8 @@ void MeasureAntennaTuningLfOnly(int *vLf125, int *vLf134, int *peakf, int *peakv
 
        FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
        FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
+       SpinDelay(50);
+       
        for (i=255; i>=19; i--) {
                WDT_HIT();
                FpgaSendCommand(FPGA_CMD_SET_DIVISOR, i);
@@ -201,7 +202,7 @@ void MeasureAntennaTuningLfOnly(int *vLf125, int *vLf134, int *peakf, int *peakv
                if (i==95) *vLf125 = adcval; // voltage at 125Khz
                if (i==89) *vLf134 = adcval; // voltage at 134Khz
 
-               LF_Results[i] = adcval>>8; // scale int to fit in byte for graphing purposes
+               LF_Results[i] = adcval >> 9; // scale int to fit in byte for graphing purposes
                if(LF_Results[i] > peak) {
                        *peakv = adcval;
                        peak = LF_Results[i];
@@ -249,7 +250,7 @@ void MeasureAntennaTuning(int mode)
                }
        }
 
-       cmd_send(CMD_MEASURED_ANTENNA_TUNING, vLf125 | (vLf134<<16), vHf, peakf | (peakv<<16), LF_Results, 256);
+       cmd_send(CMD_MEASURED_ANTENNA_TUNING, vLf125>>1 | (vLf134>>1<<16), vHf, peakf | (peakv>>1<<16), LF_Results, 256);
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
        LED_B_OFF();
        return;
@@ -291,6 +292,7 @@ void ReadMem(int addr)
 extern struct version_information version_information;
 /* bootrom version information is pointed to from _bootphase1_version_pointer */
 extern char *_bootphase1_version_pointer, _flash_start, _flash_end, _bootrom_start, _bootrom_end, __data_src_start__;
+
 void SendVersion(void)
 {
        char temp[USB_CMD_DATA_SIZE]; /* Limited data payload in USB packets */
@@ -311,10 +313,12 @@ void SendVersion(void)
        FormatVersionInformation(temp, sizeof(temp), "os: ", &version_information);
        strncat(VersionString, temp, sizeof(VersionString) - strlen(VersionString) - 1);
 
-       FpgaGatherVersion(FPGA_BITSTREAM_LF, temp, sizeof(temp));
-       strncat(VersionString, temp, sizeof(VersionString) - strlen(VersionString) - 1);
-       FpgaGatherVersion(FPGA_BITSTREAM_HF, temp, sizeof(temp));
-       strncat(VersionString, temp, sizeof(VersionString) - strlen(VersionString) - 1);
+       for (int i = 0; i < fpga_bitstream_num; i++) {
+               strncat(VersionString, fpga_version_information[i], sizeof(VersionString) - strlen(VersionString) - 1);
+               if (i < fpga_bitstream_num - 1) {
+                       strncat(VersionString, "\n", sizeof(VersionString) - strlen(VersionString) - 1);
+               }
+       }
 
        // Send Chip ID and used flash memory
        uint32_t text_and_rodata_section_size = (uint32_t)&__data_src_start__ - (uint32_t)&_flash_start;
@@ -358,17 +362,20 @@ void SendStatus(void)
 {
        BigBuf_print_status();
        Fpga_print_status();
+#ifdef WITH_SMARTCARD
+       I2C_print_status();
+#endif
        printConfig(); //LF Sampling config
        printUSBSpeed();
        Dbprintf("Various");
-       Dbprintf("  MF_DBGLEVEL......%d", MF_DBGLEVEL);
-       Dbprintf("  ToSendMax........%d",ToSendMax);
-       Dbprintf("  ToSendBit........%d",ToSendBit);
+       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)
+#if defined(WITH_ISO14443a_StandAlone) || defined(WITH_LF_StandAlone)
 
 #define OPTS 2
 
@@ -399,8 +406,8 @@ void StandAloneMode14a()
        FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
 
        int selected = 0;
-       int playing = 0, iGotoRecord = 0, iGotoClone = 0;
-       int cardRead[OPTS] = {0};
+       bool playing = false, GotoRecord = false, GotoClone = false;
+       bool cardRead[OPTS] = {false};
        uint8_t readUID[10] = {0};
        uint32_t uid_1st[OPTS]={0};
        uint32_t uid_2nd[OPTS]={0};
@@ -416,9 +423,9 @@ void StandAloneMode14a()
                WDT_HIT();
                SpinDelay(300);
 
-               if (iGotoRecord == 1 || cardRead[selected] == 0)
+               if (GotoRecord || !cardRead[selected])
                {
-                       iGotoRecord = 0;
+                       GotoRecord = false;
                        LEDsoff();
                        LED(selected + 1, 0);
                        LED(LED_RED2, 0);
@@ -443,14 +450,14 @@ void StandAloneMode14a()
                                        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;
+                                               break;
                                        }
                                        else {
                                                Dbprintf("Button press detected but no stored tag to play. (Ignoring button)");
                                                SpinDelay(300);
                                        }
                                }
-                               if (!iso14443a_select_card(uid, &hi14a_card[selected], &cuid, true, 0))
+                               if (!iso14443a_select_card(uid, &hi14a_card[selected], &cuid, true, 0, true))
                                        continue;
                                else
                                {
@@ -493,14 +500,14 @@ void StandAloneMode14a()
                        LED(selected + 1, 0);
 
                        // Next state is replay:
-                       playing = 1;
+                       playing = true;
 
-                       cardRead[selected] = 1;
+                       cardRead[selected] = true;
                }
                /* MF Classic UID clone */
-               else if (iGotoClone==1)
+               else if (GotoClone)
                {
-                       iGotoClone=0;
+                       GotoClone=false;
                        LEDsoff();
                        LED(selected + 1, 0);
                        LED(LED_ORANGE, 250);
@@ -551,7 +558,7 @@ void StandAloneMode14a()
                        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;
+                               playing = true;
                        }
                        else {
                                Dbprintf("UID from target tag: %02X%02X%02X%02X", oldBlock0[0],oldBlock0[1],oldBlock0[2],oldBlock0[3]);
@@ -569,14 +576,14 @@ void StandAloneMode14a()
                                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;
+                                       cardRead[selected] = false; // Only if the card was cloned successfully should we clear it
+                                       playing = false;
+                                       GotoRecord = true;
                                        selected = (selected+1) % OPTS;
                                }
                                else {
                                        Dbprintf("Clone failed. Back to replay mode on bank[%d]", selected);
-                                       playing = 1;
+                                       playing = true;
                                }
                        }
                        LEDsoff();
@@ -584,65 +591,59 @@ void StandAloneMode14a()
 
                }
                // Change where to record (or begin playing)
-               else if (playing==1) // button_pressed == BUTTON_SINGLE_CLICK && cardRead[selected])
+               else if (playing) // button_pressed == BUTTON_SINGLE_CLICK && cardRead[selected])
                {
                        LEDsoff();
                        LED(selected + 1, 0);
 
                        // Begin transmitting
-                       if (playing)
-                       {
-                               LED(LED_GREEN, 0);
-                               DbpString("Playing");
-                               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);
-                                               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);
-                                               }
+                       LED(LED_GREEN, 0);
+                       DbpString("Playing");
+                       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);
+                                       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 (button_action == BUTTON_SINGLE_CLICK) {
-                                               selected = (selected + 1) % OPTS;
-                                               Dbprintf("Done playing. Switching to record mode on bank %d",selected);
-                                               iGotoRecord = 1;
-                                               break;
+                                       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 (button_action == BUTTON_HOLD) {
-                                               Dbprintf("Playtime over. Begin cloning...");
-                                               iGotoClone = 1;
-                                               break;
+                                       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);
                                        }
-                                       WDT_HIT();
                                }
-
-                               /* We pressed a button so ignore it here with a delay */
-                               SpinDelay(300);
-                               LEDsoff();
-                               LED(selected + 1, 0);
+                               else if (button_action == BUTTON_SINGLE_CLICK) {
+                                       selected = (selected + 1) % OPTS;
+                                       Dbprintf("Done playing. Switching to record mode on bank %d",selected);
+                                       GotoRecord = true;
+                                       break;
+                               }
+                               else if (button_action == BUTTON_HOLD) {
+                                       Dbprintf("Playtime over. Begin cloning...");
+                                       GotoClone = true;
+                                       break;
+                               }
+                               WDT_HIT();
                        }
-                       else
-                               while(BUTTON_PRESS())
-                                       WDT_HIT();
+
+                       /* We pressed a button so ignore it here with a delay */
+                       SpinDelay(300);
+                       LEDsoff();
+                       LED(selected + 1, 0);
                }
        }
 }
-#elif WITH_LF
+#elif WITH_LF_StandAlone
 // samy's sniff and repeat routine
 void SamyRun()
 {
@@ -1051,7 +1052,12 @@ void UsbPacketReceived(uint8_t *packet, int len)
                        ReadHitagS((hitag_function)c->arg[0],(hitag_data*)c->d.asBytes);
                        break;
                case CMD_WR_HITAG_S://writer for Hitag tags args=data to write,page and key or challenge
-                       WritePageHitagS((hitag_function)c->arg[0],(hitag_data*)c->d.asBytes,c->arg[2]);
+                       if ((hitag_function)c->arg[0] < 10) {
+                               WritePageHitagS((hitag_function)c->arg[0],(hitag_data*)c->d.asBytes,c->arg[2]);
+                       }
+                       else if ((hitag_function)c->arg[0] >= 10) {
+                         WriterHitag((hitag_function)c->arg[0],(hitag_data*)c->d.asBytes, c->arg[2]);
+                       }
                        break;
 #endif
 
@@ -1085,7 +1091,7 @@ void UsbPacketReceived(uint8_t *packet, int len)
 
 #ifdef WITH_LEGICRF
                case CMD_SIMULATE_TAG_LEGIC_RF:
-                       LegicRfSimulate(c->arg[0], c->arg[1], c->arg[2]);
+                       LegicRfSimulate(c->arg[0]);
                        break;
 
                case CMD_WRITER_LEGIC_RF:
@@ -1163,6 +1169,9 @@ void UsbPacketReceived(uint8_t *packet, int len)
                case CMD_MIFAREU_WRITEBL:
                        MifareUWriteBlock(c->arg[0], c->arg[1], c->d.asBytes);
                        break;
+               case CMD_MIFARE_ACQUIRE_ENCRYPTED_NONCES:
+                       MifareAcquireEncryptedNonces(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
+                       break;
                case CMD_MIFARE_NESTED:
                        MifareNested(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
                        break;
@@ -1191,6 +1200,9 @@ void UsbPacketReceived(uint8_t *packet, int len)
                        break;
                        
                // Work with "magic Chinese" card
+               case CMD_MIFARE_CWIPE:
+                       MifareCWipe(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
+                       break;
                case CMD_MIFARE_CSETBLOCK:
                        MifareCSetBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
                        break;
@@ -1249,6 +1261,31 @@ void UsbPacketReceived(uint8_t *packet, int len)
                        HfSnoop(c->arg[0], c->arg[1]);
                        break;
 #endif
+#ifdef WITH_SMARTCARD
+               case CMD_SMART_ATR: {
+                       SmartCardAtr();
+                       break;
+               }
+               case CMD_SMART_SETCLOCK:{
+                       SmartCardSetClock(c->arg[0]);
+                       break;
+               }
+               case CMD_SMART_RAW: {
+                       SmartCardRaw(c->arg[0], c->arg[1], c->d.asBytes);
+                       break;
+               }
+               case CMD_SMART_UPLOAD: {
+                       // upload file from client
+                       uint8_t *mem = BigBuf_get_addr();
+                       memcpy( mem + c->arg[0], c->d.asBytes, USB_CMD_DATA_SIZE);
+                       cmd_send(CMD_ACK,1,0,0,0,0);
+                       break;
+               }
+               case CMD_SMART_UPGRADE: {
+                       SmartCardUpgrade(c->arg[0]);
+                       break;
+               }
+#endif
 
                case CMD_BUFF_CLEAR:
                        BigBuf_Clear();
@@ -1286,6 +1323,15 @@ void UsbPacketReceived(uint8_t *packet, int len)
                        break;
 
                case CMD_DOWNLOADED_SIM_SAMPLES_125K: {
+                       // iceman; since changing fpga_bitstreams clears bigbuff, Its better to call it before.
+                       // to be able to use this one for uploading data to device 
+                       // arg1 = 0 upload for LF usage 
+                       //        1 upload for HF usage
+                       if (c->arg[1] == 0)
+                               FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
+                       else
+                               FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
+
                        uint8_t *b = BigBuf_get_addr();
                        memcpy(b+c->arg[0], c->d.asBytes, USB_CMD_DATA_SIZE);
                        cmd_send(CMD_ACK,0,0,0,0,0);
@@ -1296,7 +1342,7 @@ void UsbPacketReceived(uint8_t *packet, int len)
                        break;
 
                case CMD_SET_LF_DIVISOR:
-                       FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
+                       FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
                        FpgaSendCommand(FPGA_CMD_SET_DIVISOR, c->arg[0]);
                        break;
 
@@ -1415,7 +1461,7 @@ void  __attribute__((noreturn)) AppMain(void)
     }
                WDT_HIT();
 
-#ifdef WITH_LF
+#ifdef WITH_LF_StandAlone
 #ifndef WITH_ISO14443a_StandAlone
                if (BUTTON_HELD(1000) > 0)
                        SamyRun();
Impressum, Datenschutz