X-Git-Url: http://cvs.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/52244230d318b663c5a389d57713e16139f0e069..53e2f2fad12bf3a270e19d0baad3c703c6f8ea64:/armsrc/appmain.c diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 4411a0c5..5995df64 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -16,6 +16,7 @@ #include "cmd.h" #include "proxmark3.h" #include "apps.h" +#include "fpga.h" #include "util.h" #include "printf.h" #include "string.h" @@ -29,9 +30,13 @@ #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 +140,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 +191,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 +201,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 +249,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 +291,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 +312,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 +361,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 +405,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 +422,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 +449,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 +499,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 +557,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 +575,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,72 +590,66 @@ 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() { StandAloneMode(); FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - int high[OPTS], low[OPTS]; + int tops[OPTS], high[OPTS], low[OPTS]; int selected = 0; int playing = 0; int cardRead = 0; @@ -683,8 +683,11 @@ void SamyRun() /* need this delay to prevent catching some weird data */ SpinDelay(500); - CmdHIDdemodFSK(1, &high[selected], &low[selected], 0); - Dbprintf("Recorded %x %x%08x", selected, high[selected], low[selected]); + CmdHIDdemodFSK(1, &tops[selected], &high[selected], &low[selected], 0); + if (tops[selected] > 0) + Dbprintf("Recorded %x %x%08x%08x", selected, tops[selected], high[selected], low[selected]); + else + Dbprintf("Recorded %x %x%08x", selected, high[selected], low[selected]); LEDsoff(); LED(selected + 1, 0); @@ -705,7 +708,10 @@ void SamyRun() LED(LED_ORANGE, 0); // record - Dbprintf("Cloning %x %x%08x", selected, high[selected], low[selected]); + if (tops[selected] > 0) + Dbprintf("Cloning %x %x%08x%08x", selected, tops[selected], high[selected], low[selected]); + else + Dbprintf("Cloning %x %x%08x", selected, high[selected], low[selected]); // wait for button to be released while(BUTTON_PRESS()) @@ -714,8 +720,11 @@ void SamyRun() /* need this delay to prevent catching some weird data */ SpinDelay(500); - CopyHIDtoT55x7(0, high[selected], low[selected], 0); - Dbprintf("Cloned %x %x%08x", selected, high[selected], low[selected]); + CopyHIDtoT55x7(tops[selected] & 0x000FFFFF, high[selected], low[selected], (tops[selected] != 0 && ((high[selected]& 0xFFFFFFC0) != 0))); + if (tops[selected] > 0) + Dbprintf("Cloned %x %x%08x%08x", selected, tops[selected], high[selected], low[selected]); + else + Dbprintf("Cloned %x %x%08x", selected, high[selected], low[selected]); LEDsoff(); LED(selected + 1, 0); @@ -748,8 +757,12 @@ void SamyRun() // wait for button to be released while(BUTTON_PRESS()) WDT_HIT(); - Dbprintf("%x %x%08x", selected, high[selected], low[selected]); - CmdHIDsimTAG(high[selected], low[selected], 0); + if (tops[selected] > 0) + Dbprintf("%x %x%08x%08x", selected, tops[selected], high[selected], low[selected]); + else + Dbprintf("%x %x%08x", selected, high[selected], low[selected]); + + CmdHIDsimTAG(tops[selected], high[selected], low[selected], 0); DbpString("Done playing"); if (BUTTON_HELD(1000) > 0) { @@ -947,10 +960,10 @@ void UsbPacketReceived(uint8_t *packet, int len) cmd_send(CMD_ACK,SnoopLF(),0,0,0,0); break; case CMD_HID_DEMOD_FSK: - CmdHIDdemodFSK(c->arg[0], 0, 0, 1); + CmdHIDdemodFSK(c->arg[0], 0, 0, 0, 1); break; case CMD_HID_SIM_TAG: - CmdHIDsimTAG(c->arg[0], c->arg[1], 1); + CmdHIDsimTAG(c->arg[0], c->arg[1], c->arg[2], 1); break; case CMD_FSK_SIM_TAG: CmdFSKsimTAG(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); @@ -1199,6 +1212,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; @@ -1257,6 +1273,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(); @@ -1294,6 +1335,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); @@ -1304,7 +1354,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; @@ -1423,7 +1473,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();