diff --git a/CHANGELOG.md b/CHANGELOG.md index ca8053022..2c08aaadc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] +- Firmware size optimization, skipping unused FPGA bitstreams (@douniwan5788) - Added pretty Hitag S config parsing (@CiRIP) - Moved Hitag S operations into separate submenu: `lf hitag s` (@CiRIP) - Added MFC keys for Sofia public transport cards (@user890104) diff --git a/Makefile.platform.sample b/Makefile.platform.sample index 018d450d2..2661a0720 100644 --- a/Makefile.platform.sample +++ b/Makefile.platform.sample @@ -20,12 +20,21 @@ PLATFORM=PM3RDV4 #PLATFORM=PM3GENERIC #PLATFORM_SIZE=256 #STANDALONE= -#SKIP_HITAG=1 -#SKIP_FELICA=1 -#SKIP_HFPLOT=1 -#SKIP_NFCBARCODE=1 -#SKIP_ZX8211=1 #SKIP_LF=1 +#SKIP_HITAG=1 +#SKIP_EM4x50=1 +#SKIP_EM4x70=1 +#SKIP_ZX8211=1 +#SKIP_HF=1 +#SKIP_ISO15693=1 +#SKIP_LEGICRF=1 +#SKIP_ISO14443b=1 +#SKIP_ISO14443a=1 +#SKIP_ICLASS=1 +#SKIP_FELICA=1 +#SKIP_NFCBARCODE=1 +#SKIP_HFSNIFF=1 +#SKIP_HFPLOT=1 # To accelerate repetitive compilations: # Install package "ccache" -> Debian/Ubuntu: /usr/lib/ccache, Fedora/CentOS/RHEL: /usr/lib64/ccache diff --git a/armsrc/appmain.c b/armsrc/appmain.c index a50fa7a56..fcd667c52 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -162,7 +162,7 @@ uint16_t SumAdc(uint8_t ch, uint8_t NbSamples) { a += ReadAdc(ch); return (a + (NbSamples >> 1) - 1); } - +#ifdef WITH_LF static void MeasureAntennaTuning(void) { uint32_t peak = 0; @@ -236,7 +236,7 @@ static void MeasureAntennaTuning(void) { reply_ng(CMD_MEASURE_ANTENNA_TUNING, PM3_SUCCESS, (uint8_t *)&payload, sizeof(payload)); LEDsoff(); } - +#endif // Measure HF in milliVolt static uint16_t MeasureAntennaTuningHfData(void) { @@ -306,7 +306,7 @@ static void SendVersion(void) { strncat(VersionString, "\n [ "_YELLOW_("FPGA")" ] \n ", sizeof(VersionString) - strlen(VersionString) - 1); for (int i = 0; i < g_fpga_bitstream_num; i++) { - strncat(VersionString, g_fpga_version_information[i], sizeof(VersionString) - strlen(VersionString) - 1); + strncat(VersionString, g_fpga_version_information[i].versionString, sizeof(VersionString) - strlen(VersionString) - 1); if (i < g_fpga_bitstream_num - 1) { strncat(VersionString, "\n ", sizeof(VersionString) - strlen(VersionString) - 1); } @@ -1610,7 +1610,9 @@ static void PacketReceived(PacketCommandNG *packet) { struct p *payload = (struct p *) packet->data.asBytes; FpgaDownloadAndGo(FPGA_BITSTREAM_HF); FpgaSendCommand(FPGA_CMD_SET_EDGE_DETECT_THRESHOLD, (payload->threshold & 0x3f) | ((payload->threshold_high & 0x3f) << 6)); +#ifdef WITH_LEGICRF LegicRfSetThreshold((uint32_t)payload->legic_threshold); +#endif break; } case CMD_HF_ISO14443A_SNIFF: { @@ -2301,10 +2303,12 @@ static void PacketReceived(PacketCommandNG *packet) { BigBuf_free(); break; } +#ifdef WITH_LF case CMD_MEASURE_ANTENNA_TUNING: { MeasureAntennaTuning(); break; } +#endif case CMD_MEASURE_ANTENNA_TUNING_HF: { if (packet->length != 1) reply_ng(CMD_MEASURE_ANTENNA_TUNING_HF, PM3_EINVARG, NULL, 0); @@ -2394,12 +2398,8 @@ static void PacketReceived(PacketCommandNG *packet) { Dbprintf("transfer to client failed :: | bytes between %d - %d (%d) | result: %d", i, i + len, len, result); } // Trigger a finish downloading signal with an ACK frame - // iceman, when did sending samplingconfig array got attached here?!? // arg0 = status of download transfer - // arg1 = RFU - // arg2 = tracelen? - // asbytes = samplingconfig array - reply_mix(CMD_ACK, 1, 0, BigBuf_get_traceLen(), getSamplingConfig(), sizeof(sample_config)); + reply_mix(CMD_ACK, 1, 0, 0, 0, 0); LED_B_OFF(); break; } @@ -2818,11 +2818,13 @@ static void PacketReceived(PacketCommandNG *packet) { break; } #endif +#ifdef WITH_LF case CMD_LF_SET_DIVISOR: { FpgaDownloadAndGo(FPGA_BITSTREAM_LF); FpgaSendCommand(FPGA_CMD_SET_DIVISOR, packet->data.asBytes[0]); break; } +#endif case CMD_SET_ADC_MUX: { switch (packet->data.asBytes[0]) { case 0: diff --git a/armsrc/em4x70.c b/armsrc/em4x70.c index 2f92dfbf1..547ce5ce2 100644 --- a/armsrc/em4x70.c +++ b/armsrc/em4x70.c @@ -377,7 +377,7 @@ static int bruteforce(const uint8_t address, const uint8_t *rnd, const uint8_t * uint8_t rev_rnd[7]; uint8_t temp_rnd[7]; - reverse_arraycopy((uint8_t *)rnd, rev_rnd, sizeof(rev_rnd)); + reverse_arraybytes_copy((uint8_t *)rnd, rev_rnd, sizeof(rev_rnd)); memcpy(temp_rnd, rnd, sizeof(temp_rnd)); for (int k = start_key; k <= 0xFFFF; ++k) { diff --git a/armsrc/fpgaloader.c b/armsrc/fpgaloader.c index 7ac52a42a..9a95a0304 100644 --- a/armsrc/fpgaloader.c +++ b/armsrc/fpgaloader.c @@ -39,7 +39,7 @@ typedef struct { typedef lz4_stream_t *lz4_streamp_t; // remember which version of the bitstream we have already downloaded to the FPGA -static int downloaded_bitstream = 0; +static int downloaded_bitstream = FPGA_BITSTREAM_UNKNOWN; // this is where the bitstreams are located in memory: extern uint32_t _binary_obj_fpga_all_bit_z_start[], _binary_obj_fpga_all_bit_z_end[]; @@ -221,14 +221,31 @@ static int get_from_fpga_combined_stream(lz4_streamp_t compressed_fpga_stream, u return *fpga_image_ptr++; } +static int bitstream_target_to_index(FPGA_config bitstream_target) { + static int8_t bitstream_index_map[FPGA_BITSTREAM_MAX] = {-1}; + + // Initialize + if (bitstream_index_map[0] == -1){ + bitstream_index_map[0] = 0; + + for (size_t i = 0; i < g_fpga_bitstream_num; i++) { + FPGA_VERSION_INFORMATION info = g_fpga_version_information[i]; + bitstream_index_map[info.target_config] = i; + } + } + + return bitstream_index_map[bitstream_target]; +} + //---------------------------------------------------------------------------- // Undo the interleaving of several FPGA config files. FPGA config files // are combined into one big file: // 288 bytes from FPGA file 1, followed by 288 bytes from FGPA file 2, etc. //---------------------------------------------------------------------------- -static int get_from_fpga_stream(int bitstream_version, lz4_streamp_t compressed_fpga_stream, uint8_t *output_buffer) { - while ((uncompressed_bytes_cnt / FPGA_INTERLEAVE_SIZE) % g_fpga_bitstream_num != (bitstream_version - 1)) { - // skip undesired data belonging to other bitstream_versions +static int get_from_fpga_stream(int bitstream_target, lz4_streamp_t compressed_fpga_stream, uint8_t *output_buffer) { + int bitstream_index = bitstream_target_to_index(bitstream_target); + while ((uncompressed_bytes_cnt / FPGA_INTERLEAVE_SIZE) % g_fpga_bitstream_num != bitstream_index) { + // skip undesired data belonging to other bitstream_targets get_from_fpga_combined_stream(compressed_fpga_stream, output_buffer); } @@ -238,7 +255,7 @@ static int get_from_fpga_stream(int bitstream_version, lz4_streamp_t compressed_ //---------------------------------------------------------------------------- // Initialize decompression of the respective (HF or LF) FPGA stream //---------------------------------------------------------------------------- -static bool reset_fpga_stream(int bitstream_version, lz4_streamp_t compressed_fpga_stream, uint8_t *output_buffer) { +static bool reset_fpga_stream(int bitstream_target, lz4_streamp_t compressed_fpga_stream, uint8_t *output_buffer) { uint8_t header[FPGA_BITSTREAM_FIXED_HEADER_SIZE]; uncompressed_bytes_cnt = 0; @@ -254,7 +271,7 @@ static bool reset_fpga_stream(int bitstream_version, lz4_streamp_t compressed_fp fpga_image_ptr = output_buffer + FPGA_RING_BUFFER_BYTES; for (uint16_t i = 0; i < FPGA_BITSTREAM_FIXED_HEADER_SIZE; i++) - header[i] = get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer); + header[i] = get_from_fpga_stream(bitstream_target, compressed_fpga_stream, output_buffer); // Check for a valid .bit file (starts with bitparse_fixed_header) if (memcmp(bitparse_fixed_header, header, FPGA_BITSTREAM_FIXED_HEADER_SIZE) == 0) @@ -276,7 +293,7 @@ static void DownloadFPGA_byte(uint8_t w) { } // Download the fpga image starting at current stream position with length FpgaImageLen bytes -static void DownloadFPGA(int bitstream_version, int FpgaImageLen, lz4_streamp_t compressed_fpga_stream, uint8_t *output_buffer) { +static void DownloadFPGA(int bitstream_target, int FpgaImageLen, lz4_streamp_t compressed_fpga_stream, uint8_t *output_buffer) { int i = 0; #if !defined XC3 AT91C_BASE_PIOA->PIO_OER = GPIO_FPGA_ON; @@ -354,7 +371,7 @@ static void DownloadFPGA(int bitstream_version, int FpgaImageLen, lz4_streamp_t #endif for (i = 0; i < FpgaImageLen; i++) { - int b = get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer); + int b = get_from_fpga_stream(bitstream_target, compressed_fpga_stream, output_buffer); if (b < 0) { Dbprintf("Error %d during FpgaDownload", b); break; @@ -383,14 +400,14 @@ static void DownloadFPGA(int bitstream_version, int FpgaImageLen, lz4_streamp_t * (big endian), bytes content. Except for section 'e' which has 4 bytes * length. */ -static int bitparse_find_section(int bitstream_version, char section_name, uint32_t *section_length, lz4_streamp_t compressed_fpga_stream, uint8_t *output_buffer) { +static int bitparse_find_section(int bitstream_target, char section_name, uint32_t *section_length, lz4_streamp_t compressed_fpga_stream, uint8_t *output_buffer) { #define MAX_FPGA_BIT_STREAM_HEADER_SEARCH 100 // maximum number of bytes to search for the requested section int result = 0; uint16_t numbytes = 0; while (numbytes < MAX_FPGA_BIT_STREAM_HEADER_SEARCH) { - char current_name = get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer); + char current_name = get_from_fpga_stream(bitstream_target, compressed_fpga_stream, output_buffer); numbytes++; uint32_t current_length = 0; if (current_name < 'a' || current_name > 'e') { @@ -401,10 +418,10 @@ static int bitparse_find_section(int bitstream_version, char section_name, uint3 switch (current_name) { case 'e': /* Four byte length field */ - current_length += get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer) << 24; - current_length += get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer) << 16; - current_length += get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer) << 8; - current_length += get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer) << 0; + current_length += get_from_fpga_stream(bitstream_target, compressed_fpga_stream, output_buffer) << 24; + current_length += get_from_fpga_stream(bitstream_target, compressed_fpga_stream, output_buffer) << 16; + current_length += get_from_fpga_stream(bitstream_target, compressed_fpga_stream, output_buffer) << 8; + current_length += get_from_fpga_stream(bitstream_target, compressed_fpga_stream, output_buffer) << 0; numbytes += 4; if (current_length > 300 * 1024) { /* section e should never exceed about 300KB, if the length is too big limit it but still send the bitstream just in case */ @@ -412,8 +429,8 @@ static int bitparse_find_section(int bitstream_version, char section_name, uint3 } break; default: /* Two byte length field */ - current_length += get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer) << 8; - current_length += get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer) << 0; + current_length += get_from_fpga_stream(bitstream_target, compressed_fpga_stream, output_buffer) << 8; + current_length += get_from_fpga_stream(bitstream_target, compressed_fpga_stream, output_buffer) << 0; numbytes += 2; if (current_length > 64) { /* if text field is too long, keep it but truncate it */ @@ -429,7 +446,7 @@ static int bitparse_find_section(int bitstream_version, char section_name, uint3 } for (uint32_t i = 0; i < current_length && numbytes < MAX_FPGA_BIT_STREAM_HEADER_SEARCH; i++) { - get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer); + get_from_fpga_stream(bitstream_target, compressed_fpga_stream, output_buffer); numbytes++; } } @@ -438,16 +455,16 @@ static int bitparse_find_section(int bitstream_version, char section_name, uint3 //---------------------------------------------------------------------------- // Change FPGA image status, if image loaded. -// bitstream_version is your new fpga image version +// bitstream_target is your new fpga image version // return true if can change. // return false if image is unloaded. //---------------------------------------------------------------------------- #if defined XC3 -static bool FpgaConfCurrentMode(int bitstream_version) { +static bool FpgaConfCurrentMode(int bitstream_target) { // fpga "XC3S100E" image merge // If fpga image is no init // We need load hf_lf_allinone.bit - if (downloaded_bitstream != 0) { + if (downloaded_bitstream != FPGA_BITSTREAM_UNKNOWN) { // test start // PIO controls the following pins AT91C_BASE_PIOA->PIO_PER = GPIO_FPGA_SWITCH; @@ -457,13 +474,13 @@ static bool FpgaConfCurrentMode(int bitstream_version) { // try to turn off antenna FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - if (bitstream_version == FPGA_BITSTREAM_LF) { + if (bitstream_target == FPGA_BITSTREAM_LF) { LOW(GPIO_FPGA_SWITCH); } else { HIGH(GPIO_FPGA_SWITCH); } // update downloaded_bitstream - downloaded_bitstream = bitstream_version; + downloaded_bitstream = bitstream_target; // turn off antenna FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); return true; @@ -476,10 +493,10 @@ static bool FpgaConfCurrentMode(int bitstream_version) { // Check which FPGA image is currently loaded (if any). If necessary // decompress and load the correct (HF or LF) image to the FPGA //---------------------------------------------------------------------------- -void FpgaDownloadAndGo(int bitstream_version) { +void FpgaDownloadAndGo(int bitstream_target) { // check whether or not the bitstream is already loaded - if (downloaded_bitstream == bitstream_version) { + if (downloaded_bitstream == bitstream_target) { FpgaEnableTracing(); return; } @@ -487,7 +504,7 @@ void FpgaDownloadAndGo(int bitstream_version) { #if defined XC3 // If we can change image version // direct return. - if (FpgaConfCurrentMode(bitstream_version)) { + if (FpgaConfCurrentMode(bitstream_target)) { return; } #endif @@ -506,19 +523,19 @@ void FpgaDownloadAndGo(int bitstream_version) { compressed_fpga_stream.lz4StreamDecode = &lz4StreamDecode_body; uint8_t *output_buffer = BigBuf_malloc(FPGA_RING_BUFFER_BYTES); - if (!reset_fpga_stream(bitstream_version, &compressed_fpga_stream, output_buffer)) + if (!reset_fpga_stream(bitstream_target, &compressed_fpga_stream, output_buffer)) return; uint32_t bitstream_length; - if (bitparse_find_section(bitstream_version, 'e', &bitstream_length, &compressed_fpga_stream, output_buffer)) { - DownloadFPGA(bitstream_version, bitstream_length, &compressed_fpga_stream, output_buffer); - downloaded_bitstream = bitstream_version; + if (bitparse_find_section(bitstream_target, 'e', &bitstream_length, &compressed_fpga_stream, output_buffer)) { + DownloadFPGA(bitstream_target, bitstream_length, &compressed_fpga_stream, output_buffer); + downloaded_bitstream = bitstream_target; } #if defined XC3 // first download fpga image to hf // we need to change fpga status to hf - FpgaConfCurrentMode(bitstream_version); + FpgaConfCurrentMode(bitstream_target); #endif // turn off antenna @@ -603,7 +620,7 @@ void SetAdcMuxFor(uint32_t whichGpio) { void Fpga_print_status(void) { DbpString(_CYAN_("Current FPGA image")); - Dbprintf(" mode....................%s", g_fpga_version_information[downloaded_bitstream - 1]); + Dbprintf(" mode.................... %s", g_fpga_version_information[bitstream_target_to_index(downloaded_bitstream)]); } int FpgaGetCurrent(void) { diff --git a/armsrc/fpgaloader.h b/armsrc/fpgaloader.h index 3e5801e46..0786e608c 100644 --- a/armsrc/fpgaloader.h +++ b/armsrc/fpgaloader.h @@ -20,6 +20,7 @@ #define __FPGALOADER_H #include "common.h" +#include "fpga.h" #define FpgaDisableSscDma(void) AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS; #define FpgaEnableSscDma(void) AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTEN; @@ -164,8 +165,8 @@ void FpgaSendCommand(uint16_t cmd, uint16_t v); void FpgaWriteConfWord(uint16_t v); void FpgaEnableTracing(void); void FpgaDisableTracing(void); -void FpgaDownloadAndGo(int bitstream_version); -// void FpgaGatherVersion(int bitstream_version, char *dst, int len); +void FpgaDownloadAndGo(int bitstream_target); +// void FpgaGatherVersion(int bitstream_target, char *dst, int len); void FpgaSetupSsc(uint16_t fpga_mode); void SetupSpi(int mode); bool FpgaSetupSscDma(uint8_t *buf, uint16_t len); diff --git a/armsrc/optimized_cipherutils.c b/armsrc/optimized_cipherutils.c index 66a618291..4260ea12d 100644 --- a/armsrc/optimized_cipherutils.c +++ b/armsrc/optimized_cipherutils.c @@ -114,24 +114,3 @@ uint64_t x_bytes_to_num(uint8_t *src, size_t len) { return num; } -uint8_t reversebyte(uint8_t b) { - b = (b & 0xF0) >> 4 | (b & 0x0F) << 4; - b = (b & 0xCC) >> 2 | (b & 0x33) << 2; - b = (b & 0xAA) >> 1 | (b & 0x55) << 1; - return b; -} - -void reverse_arraybytes(uint8_t *arr, size_t len) { - size_t i; - for (i = 0; i < len ; i++) { - arr[i] = reversebyte(arr[i]); - } -} - -void reverse_arraycopy(uint8_t *arr, uint8_t *dest, size_t len) { - size_t i; - for (i = 0; i < len ; i++) { - dest[i] = reversebyte(arr[i]); - } -} - diff --git a/armsrc/optimized_cipherutils.h b/armsrc/optimized_cipherutils.h index 8d8a75f8c..d6a046bf9 100644 --- a/armsrc/optimized_cipherutils.h +++ b/armsrc/optimized_cipherutils.h @@ -57,7 +57,4 @@ int bitsLeft(BitstreamIn_t *stream); void push6bits(BitstreamOut_t *stream, uint8_t bits); void x_num_to_bytes(uint64_t n, size_t len, uint8_t *dest); uint64_t x_bytes_to_num(uint8_t *src, size_t len); -uint8_t reversebyte(uint8_t b); -void reverse_arraybytes(uint8_t *arr, size_t len); -void reverse_arraycopy(uint8_t *arr, uint8_t *dest, size_t len); #endif // CIPHERUTILS_H diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index ce371155c..a5580a9f4 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -44,6 +44,7 @@ #include "preferences.h" #include "mifare/gen4.h" #include "generator.h" // keygens. +#include "fpga.h" static int CmdHelp(const char *Cmd); diff --git a/client/src/cmdhw.c b/client/src/cmdhw.c index a270d2f1b..6b4118d02 100644 --- a/client/src/cmdhw.c +++ b/client/src/cmdhw.c @@ -1468,12 +1468,12 @@ static command_t CommandTable[] = { {"ping", CmdPing, IfPm3Present, "Test if the Proxmark3 is responsive"}, {"readmem", CmdReadmem, IfPm3Present, "Read from MCU flash"}, {"reset", CmdReset, IfPm3Present, "Reset the device"}, - {"setlfdivisor", CmdSetDivisor, IfPm3Present, "Drive LF antenna at 12MHz / (divisor + 1)"}, - {"sethfthresh", CmdSetHFThreshold, IfPm3Present, "Set thresholds in HF/14a mode"}, + {"setlfdivisor", CmdSetDivisor, IfPm3Lf, "Drive LF antenna at 12MHz / (divisor + 1)"}, + {"sethfthresh", CmdSetHFThreshold, IfPm3Iso14443a, "Set thresholds in HF/14a mode"}, {"setmux", CmdSetMux, IfPm3Present, "Set the ADC mux to a specific value"}, {"standalone", CmdStandalone, IfPm3Present, "Start installed standalone mode on device"}, {"tia", CmdTia, IfPm3Present, "Trigger a Timing Interval Acquisition to re-adjust the RealTimeCounter divider"}, - {"tune", CmdTune, IfPm3Present, "Measure tuning of device antenna"}, + {"tune", CmdTune, IfPm3Lf, "Measure tuning of device antenna"}, {NULL, NULL, NULL, NULL} }; diff --git a/client/src/cmdlf.c b/client/src/cmdlf.c index 16c3124a0..2f179a948 100644 --- a/client/src/cmdlf.c +++ b/client/src/cmdlf.c @@ -34,7 +34,7 @@ #include "cmdhw.h" // for setting FPGA image #include "cmdlfawid.h" // for awid menu #include "cmdlfem.h" // for em menu -#include "cmdlfem410x.h" // for em4x menu +#include "cmdlfem410x.h" // for em4x menu #include "cmdlfem4x05.h" // for em4x05 / 4x69 #include "cmdlfem4x50.h" // for em4x50 #include "cmdlfem4x70.h" // for em4x70 @@ -67,6 +67,7 @@ #include "cmdlfzx8211.h" // for ZX8211 menu #include "crc.h" #include "pm3_cmd.h" // for LF_CMDREAD_MAX_EXTRA_SYMBOLS +#include "fpga.h" // for set_fpga_mode static int CmdHelp(const char *Cmd); @@ -1552,7 +1553,7 @@ static bool check_chiptype(bool getDeviceData) { //check for em4x05/em4x69 chips first uint32_t word = 0; - if (em4x05_isblock0(&word)) { + if (IfPm3EM4x50() && em4x05_isblock0(&word)) { PrintAndLogEx(SUCCESS, "Chipset detection: " _GREEN_("EM4x05 / EM4x69")); PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf em 4x05`") " commands"); retval = true; @@ -1569,7 +1570,7 @@ static bool check_chiptype(bool getDeviceData) { #if !defined ICOPYX // check for em4x50 chips - if (detect_4x50_block()) { + if (IfPm3EM4x50() && detect_4x50_block()) { PrintAndLogEx(SUCCESS, "Chipset detection: " _GREEN_("EM4x50")); PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf em 4x50`") " commands"); retval = true; @@ -1577,7 +1578,7 @@ static bool check_chiptype(bool getDeviceData) { } // check for em4x70 chips - if (detect_4x70_block()) { + if (IfPm3EM4x70() && detect_4x70_block()) { PrintAndLogEx(SUCCESS, "Chipset detection: " _GREEN_("EM4x70")); PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf em 4x70`") " commands"); retval = true; diff --git a/client/src/loclass/cipher.c b/client/src/loclass/cipher.c index 974eb5060..733f6479a 100644 --- a/client/src/loclass/cipher.c +++ b/client/src/loclass/cipher.c @@ -34,6 +34,7 @@ #include "cipher.h" #include "cipherutils.h" +#include "commonutil.h" #include #include #include diff --git a/client/src/loclass/cipherutils.c b/client/src/loclass/cipherutils.c index f3572b823..9a55979ff 100644 --- a/client/src/loclass/cipherutils.c +++ b/client/src/loclass/cipherutils.c @@ -125,18 +125,6 @@ uint64_t x_bytes_to_num(uint8_t *src, size_t len) { return num; } -void reverse_arraybytes(uint8_t *arr, size_t len) { - for (size_t i = 0; i < len ; i++) { - arr[i] = reflect8(arr[i]); - } -} - -void reverse_arraycopy(uint8_t *arr, uint8_t *dest, size_t len) { - for (size_t i = 0; i < len ; i++) { - dest[i] = reflect8(arr[i]); - } -} - void printarr(const char *name, uint8_t *arr, int len) { if (name == NULL || arr == NULL) return; diff --git a/client/src/loclass/cipherutils.h b/client/src/loclass/cipherutils.h index c2538901e..490c16d3e 100644 --- a/client/src/loclass/cipherutils.h +++ b/client/src/loclass/cipherutils.h @@ -62,9 +62,6 @@ int testCipherUtils(void); void push6bits(BitstreamOut_t *stream, uint8_t bits); void x_num_to_bytes(uint64_t n, size_t len, uint8_t *dest); uint64_t x_bytes_to_num(uint8_t *src, size_t len); -uint8_t reversebyte(uint8_t b); -void reverse_arraybytes(uint8_t *arr, size_t len); -void reverse_arraycopy(uint8_t *arr, uint8_t *dest, size_t len); void printarr(const char *name, uint8_t *arr, int len); void printarr_human_readable(const char *title, uint8_t *arr, int len); #endif // CIPHERUTILS_H diff --git a/common/commonutil.c b/common/commonutil.c index 157998949..87bc051c2 100644 --- a/common/commonutil.c +++ b/common/commonutil.c @@ -549,3 +549,17 @@ bool hexstr_to_byte_array(const char *hexstr, uint8_t *d, size_t *n) { } return true; } + +void reverse_arraybytes(uint8_t *arr, size_t len) { + size_t i; + for (i = 0; i < len ; i++) { + arr[i] = reflect8(arr[i]); + } +} + +void reverse_arraybytes_copy(uint8_t *arr, uint8_t *dest, size_t len) { + size_t i; + for (i = 0; i < len ; i++) { + dest[i] = reflect8(arr[i]); + } +} \ No newline at end of file diff --git a/common/commonutil.h b/common/commonutil.h index a7ba4bf98..c5c7279d9 100644 --- a/common/commonutil.h +++ b/common/commonutil.h @@ -130,4 +130,7 @@ void reverse_array(uint8_t *d, size_t n); void reverse_array_copy(const uint8_t *src, int src_len, uint8_t *dest); bool hexstr_to_byte_array(const char *hexstr, uint8_t *d, size_t *n); + +void reverse_arraybytes(uint8_t *arr, size_t len); +void reverse_arraybytes_copy(uint8_t *arr, uint8_t *dest, size_t len); #endif diff --git a/common_arm/Makefile.hal b/common_arm/Makefile.hal index d86d1a76d..6c9318fd5 100644 --- a/common_arm/Makefile.hal +++ b/common_arm/Makefile.hal @@ -73,6 +73,7 @@ and you can specify which parts to skip in order to reduce the size: SKIP_LF=1 SKIP_HITAG=1 SKIP_EM4x50=1 +SKIP_EM4x70=1 SKIP_ISO15693=1 SKIP_LEGICRF=1 SKIP_ISO14443b=1 @@ -96,32 +97,59 @@ PLTNAME = Unknown Platform PLATFORM_FPGA = fpga-undefined ifeq ($(PLATFORM),PM3RDV4) - # FPGA bitstream files, the order matters! - FPGA_BITSTREAMS = fpga_pm3_lf.bit fpga_pm3_hf.bit fpga_pm3_felica.bit fpga_pm3_hf_15.bit + # FPGA bitstream files, the order doesn't matter anymore + FPGA_BITSTREAMS = fpga_pm3_hf.bit + ifneq ($(SKIP_LF),1) + FPGA_BITSTREAMS += fpga_pm3_lf.bit + endif + ifneq ($(SKIP_FELICA),1) + FPGA_BITSTREAMS += fpga_pm3_felica.bit + endif + ifneq ($(SKIP_ISO15693),1) + FPGA_BITSTREAMS += fpga_pm3_hf_15.bit + endif PLATFORM_DEFS = -DWITH_SMARTCARD -DWITH_FLASH -DRDV4 PLTNAME = Proxmark3 RDV4 PLATFORM_FPGA = xc2s30 RDV4 = yes else ifeq ($(PLATFORM),PM3OTHER) $(warning PLATFORM=PM3OTHER is deprecated, please use PLATFORM=PM3GENERIC) - # FPGA bitstream files, the order matters! - FPGA_BITSTREAMS = fpga_pm3_lf.bit fpga_pm3_hf.bit fpga_pm3_felica.bit fpga_pm3_hf_15.bit + # FPGA bitstream files, the order doesn't matter anymore + FPGA_BITSTREAMS = fpga_pm3_hf.bit + ifneq ($(SKIP_LF),1) + FPGA_BITSTREAMS += fpga_pm3_lf.bit + endif + ifneq ($(SKIP_FELICA),1) + FPGA_BITSTREAMS += fpga_pm3_felica.bit + endif + ifneq ($(SKIP_ISO15693),1) + FPGA_BITSTREAMS += fpga_pm3_hf_15.bit + endif PLTNAME = Proxmark3 generic target PLATFORM_FPGA = xc2s30 ifeq ($(LED_ORDER),PM3EASY) PLATFORM_DEFS = -DLED_ORDER_PM3EASY endif else ifeq ($(PLATFORM),PM3GENERIC) - # FPGA bitstream files, the order matters! - FPGA_BITSTREAMS = fpga_pm3_lf.bit fpga_pm3_hf.bit fpga_pm3_felica.bit fpga_pm3_hf_15.bit + # FPGA bitstream files, the order doesn't matter anymore + FPGA_BITSTREAMS = fpga_pm3_hf.bit + ifneq ($(SKIP_LF),1) + FPGA_BITSTREAMS += fpga_pm3_lf.bit + endif + ifneq ($(SKIP_FELICA),1) + FPGA_BITSTREAMS += fpga_pm3_felica.bit + endif + ifneq ($(SKIP_ISO15693),1) + FPGA_BITSTREAMS += fpga_pm3_hf_15.bit + endif PLTNAME = Proxmark3 generic target PLATFORM_FPGA = xc2s30 ifeq ($(LED_ORDER),PM3EASY) PLATFORM_DEFS = -DLED_ORDER_PM3EASY endif else ifeq ($(PLATFORM),PM3ICOPYX) - # FPGA bitstream files, the order matters - only hf has a bitstream, the other 3 files are 0 bytes - FPGA_BITSTREAMS = fpga_icopyx_lf.bit fpga_icopyx_hf.bit fpga_icopyx_felica.bit fpga_icopyx_hf_15.bit + # FPGA bitstream files, the order doesn't matter anymore - only hf has a bitstream + FPGA_BITSTREAMS = fpga_icopyx_hf.bit PLATFORM_DEFS = -DWITH_FLASH -DICOPYX -DXC3 PLTNAME = iCopy-X with XC3S100E PLATFORM_FPGA = xc3s100e diff --git a/common_fpga/fpga.h b/common_fpga/fpga.h index 35143ec6f..8248896da 100644 --- a/common_fpga/fpga.h +++ b/common_fpga/fpga.h @@ -32,8 +32,25 @@ #define FPGA_RING_BUFFER_BYTES (1024 * 30) #define FPGA_TRACE_SIZE 3072 +// definitions for multiple FPGA config files support +typedef enum +{ + FPGA_BITSTREAM_UNKNOWN = 0, + FPGA_BITSTREAM_LF = 1, + FPGA_BITSTREAM_HF, + FPGA_BITSTREAM_HF_FELICA, + FPGA_BITSTREAM_HF_15, + FPGA_BITSTREAM_MAX = FPGA_BITSTREAM_HF_15, +} FPGA_config; + +typedef struct +{ + const char *const versionString; + const FPGA_config target_config; +} FPGA_VERSION_INFORMATION; + static const uint8_t bitparse_fixed_header[] = {0x00, 0x09, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0x00, 0x01}; extern const int g_fpga_bitstream_num; -extern const char *const g_fpga_version_information[]; +extern const FPGA_VERSION_INFORMATION g_fpga_version_information[]; #endif diff --git a/fpga/Makefile b/fpga/Makefile index 8a95c7638..821ac0ec7 100644 --- a/fpga/Makefile +++ b/fpga/Makefile @@ -182,12 +182,6 @@ work: $(Q)$(XILINX_TOOLS_PREFIX)par $(VERBOSITY) -w $< $@ %.bit: %.ncd - # Hacky hack, make empty files for icopyx - if echo "$@" | grep -qi "icopyx"; then \ - truncate -s0 ../fpga_icopyx_lf.bit; \ - truncate -s0 ../fpga_icopyx_hf_15.bit; \ - truncate -s0 ../fpga_icopyx_felica.bit; \ - fi $(Q)$(RM) $@ $*.drc $*.rbt $(info [=] BITGEN $@) $(Q)$(XILINX_TOOLS_PREFIX)bitgen $(VERBOSITY) -w $* $@ diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 78a074b6e..bb459f3fb 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -891,11 +891,6 @@ typedef struct { # define UART_TCP_LOCAL_CLIENT_RX_TIMEOUT_MS 40 # define UART_UDP_LOCAL_CLIENT_RX_TIMEOUT_MS 20 -// definitions for multiple FPGA config files support -#define FPGA_BITSTREAM_LF 1 -#define FPGA_BITSTREAM_HF 2 -#define FPGA_BITSTREAM_HF_FELICA 3 -#define FPGA_BITSTREAM_HF_15 4 // CMD_DEVICE_INFO response packet has flags in arg[0], flag definitions: /* Whether a bootloader that understands the g_common_area is present */ diff --git a/tools/fpga_compress/fpga_compress.c b/tools/fpga_compress/fpga_compress.c index ab1d93243..97ba90024 100644 --- a/tools/fpga_compress/fpga_compress.c +++ b/tools/fpga_compress/fpga_compress.c @@ -420,8 +420,9 @@ static void print_version_info_preamble(FILE *outfile, int num_infiles) { fprintf(outfile, "// This file is generated by fpga_compress. Don't edit!\n"); fprintf(outfile, "//-----------------------------------------------------------------------------\n"); fprintf(outfile, "\n\n"); + fprintf(outfile, "#include \"fpga.h\"\n\n"); fprintf(outfile, "const int g_fpga_bitstream_num = %d;\n", num_infiles); - fprintf(outfile, "const char *const g_fpga_version_information[%d] = {\n", num_infiles); + fprintf(outfile, "const FPGA_VERSION_INFORMATION g_fpga_version_information[%d] = {\n", num_infiles); } static int generate_fpga_version_info(FILE *infile[], char *infile_names[], int num_infiles, FILE *outfile) { @@ -432,7 +433,19 @@ static int generate_fpga_version_info(FILE *infile[], char *infile_names[], int for (int i = 0; i < num_infiles; i++) { FpgaGatherVersion(infile[i], infile_names[i], version_string, sizeof(version_string)); - fprintf(outfile, " \" %s\"", version_string); + fprintf(outfile, " { \"%s\"", version_string); + + if (!memcmp("fpga_pm3_lf.ncd", version_string, sizeof("fpga_pm3_lf.ncd") - 1)) + fprintf(outfile, ", FPGA_BITSTREAM_LF }"); + else if (!memcmp("fpga_pm3_hf_15.ncd", version_string, sizeof("fpga_pm3_hf_15.ncd") - 1)) + fprintf(outfile, ", FPGA_BITSTREAM_HF_15 }"); + else if (!memcmp("fpga_pm3_hf.ncd", version_string, sizeof("fpga_pm3_hf.ncd") - 1)) + fprintf(outfile, ", FPGA_BITSTREAM_HF }"); + else if (!memcmp("fpga_pm3_felica.ncd", version_string, sizeof("fpga_pm3_felica.ncd") - 1)) + fprintf(outfile, ", FPGA_BITSTREAM_HF_FELICA }"); + else + fprintf(outfile, ", FPGA_BITSTREAM_UNKNOWN }"); + if (i != num_infiles - 1) { fprintf(outfile, ","); }