diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 3b04ea5f8..940722506 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,6 +1,9 @@ --- name: Bug report about: Create a report to help us improve +title: '' +labels: '' +assignees: '' --- diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 000000000..ff12e62f1 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: "[idea]" +labels: Request, enhancement +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c7adf3a6..44a6fc2d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,9 @@ 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] + - Change 'hf 14a antifuzz' - original implementation (@asfabw), reworked a bit + - Fix 'hf mf fchk' (@iceman) + - Fix 'usb slow on posix based systems' (@fl0-0) - Change 'lf pcf7931' - improved read code (@sguerrini97) - Change 'hf felica list' - started with some FeliCa annotations (@iceman) - Fix 'hf tune' - now works as expected (@iceman) diff --git a/README.md b/README.md index 94f7b94d6..c8c04f852 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,33 @@ Proxmark3 RDV40 dedicated repo, based on iceman fork ## Notice This repo is based on iceman fork for proxmark3. It is dedicated to bring the most out of the new features for proxmark3 RDV40 device. +# Donations +Nothing says thank you as much as a donation, https://www.patreon.com/iceman1001 + +## ToC + +- Coverity Scan Config & Run +- Whats changed? +- Why didn't you based it on offical PM3 Master? +- Why don't you add this or that functionality? +- PM3 GUI +- Development +- KALI and ARCHLINUX users +- Setup and build for UBUNTU +- Setup and build for ArchLinux +- Homebrew (Mac OS X) +- Upgrading HomeBrew tap formula +- Building on Windows +- Gator96100 distro +- Build and run +- Validating proxmark client functionality +- Run the following commands +- Quit client +- First things on your RDV40 +- Verify sim module firmware version + +- The end + ## Coverity Scan Config & Run Download the Coverity Scan Self-buld and install it. You will need to configure ARM-NON-EABI- Compiler for it to use: @@ -37,19 +64,28 @@ The separation from offical pm3 repo gives us very much freedom to create a firm Give us a hint, and we'll see if we can't merge in the stuff you have. ## PM3 GUI -The official PM3-GUI from Gaucho will not work. -The new universial GUI will work. +The official PM3-GUI from Gaucho will not work. +The new universial GUI will work. [Proxmark3 Univerisal GUI](https://github.com/burma69/PM3UniversalGUI) ## Development This fork now compiles just fine on - Windows/mingw environment with Qt5.6.1 & GCC 4.8 - Ubuntu 1404, 1510, 1604, 1804 - Mac OS X / Homebrew + - ParrotOS + - WSL (Windows subsystem linux) on Windows 10 - Docker container ## KALI and ARCHLINUX users Kali and ArchLinux users usually must kill their modem manager in order for the proxmark3 to enumerate properly. -`sudo apt remove modemmanager` +```sh +sudo apt remove modemmanager +``` +or +```sh +systemctl stop ModemManager +systemctl disable ModemManager +``` ## Setup and build for UBUNTU GC made updates to allow this to build easily on Ubuntu 14.04.2 LTS, 15.10 or 16.04 @@ -61,7 +97,7 @@ I have also added this script to the fork. https://github.com/RfidResearchGroup/proxmark3/blob/master/install.sh - Run -`sudo apt-get install p7zip git build-essential libreadline5 libreadline-dev libusb-0.1-4 libusb-dev libqt4-dev perl pkg-config wget libncurses5-dev gcc-arm-none-eabi libjansson-dev` +`sudo apt-get install p7zip git build-essential libreadline5 libreadline-dev libusb-0.1-4 libusb-dev libqt4-dev perl pkg-config wget libncurses5-dev gcc-arm-none-eabi` - Clone fork `git clone https://github.com/RfidResearchGroup/proxmark3.git` @@ -86,7 +122,7 @@ https://github.com/RfidResearchGroup/proxmark3/blob/master/install.sh ## Setup and build for ArchLinux - Run -`sudo pacman -Sy base-devel p7zip libusb readline ncurses libjansson-dev arm-none-eabi-newlib --needed` +`sudo pacman -Sy base-devel p7zip libusb readline ncurses arm-none-eabi-newlib --needed` `yaourt -S termcap` - Remove modemmanager @@ -224,7 +260,7 @@ If all went well you should get some information about the firmware and memory u > > pm3 --> -### run the following commands +### Run the following commands pm3 --> hw status pm3 --> hw version pm3 --> hw tune @@ -240,6 +276,46 @@ You are now ready to use your newly upgraded proxmark3 device. Many commands us pm3 --> quit +### First things on your RDV40 +You will need to run these commands to make sure your rdv4 is prepared + + pm3 --> mem load f default_keys m + pm3 --> mem load f default_pwd t + pm3 --> mem load f default_iclass_keys i + pm3 --> lf t55xx deviceconfig a 29 b 17 c 15 d 47 e 15 p + +### Verify sim module firmware version +To make sure you got the latest sim module firmware. +_Lastest version is v3.10_ + + pm3 --> hw status + +Find version in the long output, look for these two lines + + #db# Smart card module (ISO 7816) + #db# version.................v2.06 + +This version is obselete. The following command upgrades your device sim module firmware. +Don't not turn of your device during the execution of this command. + + pm3 --> sc upgrade f ../tools/simmodule/SIM010.BIN + +You get the following output, this is a successful execution. + + [!] WARNING - Smartcard socket firmware upgrade. + [!] A dangerous command, do wrong and you will brick the smart card socket + [+] Smartcard socket firmware uploading to PM3 + .. + [+] Smartcard socket firmware updating, don't turn off your PM3! + #db# FW 0000 + #db# FW 0080 + #db# FW 0100 + #db# FW 0180 + #db# FW 0200 + #db# FW 0280 + [+] Smartcard socket firmware upgraded successful + + ## the end `iceman at host iuse.se` diff --git a/armsrc/Makefile b/armsrc/Makefile index 76f3a0173..efc443227 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -21,7 +21,7 @@ APP_CFLAGS = -DWITH_CRC \ -DWITH_ISO14443a \ -DWITH_ICLASS \ -DWITH_FELICA \ - -DWITH_FLASH \ + -DWITH_FLASH \ -DWITH_SMARTCARD \ -DWITH_FPC \ -DWITH_HFSNOOP \ @@ -191,7 +191,7 @@ $(OBJDIR)/fpga_all.bit.z: $(FPGA_BITSTREAMS) $(FPGA_COMPRESSOR) $(FPGA_COMPRESSOR) $(filter %.bit,$^) $@ $(FPGA_COMPRESSOR): - make -C ../client $(notdir $(FPGA_COMPRESSOR)) + $(MAKE) -C ../client $(notdir $(FPGA_COMPRESSOR)) $(OBJDIR)/fullimage.stage1.elf: $(VERSIONOBJ) $(OBJDIR)/fpga_all.o $(THUMBOBJ) $(ARMOBJ) $(CC) $(LDFLAGS) -Wl,-T,ldscript,-Map,$(patsubst %.elf,%.map,$@) -o $@ $^ $(LIBS) diff --git a/armsrc/Standalone/hf_bog.c b/armsrc/Standalone/hf_bog.c index 9079d5df3..65254bd5c 100644 --- a/armsrc/Standalone/hf_bog.c +++ b/armsrc/Standalone/hf_bog.c @@ -271,6 +271,11 @@ void RAMFUNC SniffAndStore(uint8_t param) { uint16_t writelen = Flash_WriteData(0, total_data, memoffset + 4 * auth_attempts); if (MF_DBGLEVEL > 1) Dbprintf("[!] Wrote %u bytes into flash mem", writelen); + // If pwd saved successfully, blink led A three times + if (writelen > 0) { + SpinErr(0, 200, 5); // blink led A + } + SpinDelay(100); // Reset the SPI Baudrate to the default value (24MHz) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 8759f93c4..0bf9ccb9d 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -724,6 +724,9 @@ void UsbPacketReceived(uint8_t *packet, int len) { case CMD_T55XX_RESET_READ: T55xxResetRead(); break; + case CMD_T55XX_CHKPWDS: + T55xx_ChkPwds(); + break; case CMD_PCF7931_READ: ReadPCF7931(); break; diff --git a/armsrc/apps.h b/armsrc/apps.h index 7e45d5e50..d17d9ef4b 100644 --- a/armsrc/apps.h +++ b/armsrc/apps.h @@ -103,6 +103,8 @@ void T55xxWriteBlock(uint32_t Data, uint8_t Block, uint32_t Pwd, uint8_t PwdMode void T55xxWriteBlockExt(uint32_t Data, uint8_t Block, uint32_t Pwd, uint8_t PwdMode); void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd); void T55xxWakeUp(uint32_t Pwd); +void T55xx_ChkPwds(void); + void TurnReadLFOn(uint32_t delay); void EM4xReadWord(uint8_t addr, uint32_t pwd, uint8_t usepwd); void EM4xWriteWord(uint32_t flag, uint32_t data, uint32_t pwd); diff --git a/armsrc/epa.c b/armsrc/epa.c index 68b2711da..e97fda7a0 100644 --- a/armsrc/epa.c +++ b/armsrc/epa.c @@ -108,7 +108,7 @@ int EPA_APDU(uint8_t *apdu, size_t length, uint8_t *response) switch(iso_type) { case 'a': - return iso14_apdu(apdu, (uint16_t) length, response, NULL); + return iso14_apdu(apdu, (uint16_t) length, false, response, NULL); break; case 'b': return iso14443b_apdu(apdu, length, response); diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 257c39b1f..4267d28af 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -2219,13 +2219,16 @@ b8 b7 b6 b5 b4 b3 b2 b1 b5,b6 = 00 - DESELECT 11 - WTX */ -int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, void *data, uint8_t *res) { +int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, bool send_chaining, void *data, uint8_t *res) { uint8_t parity[MAX_PARITY_SIZE] = {0x00}; uint8_t real_cmd[cmd_len + 4]; if (cmd_len) { // ISO 14443 APDU frame: PCB [CID] [NAD] APDU CRC PCB=0x02 real_cmd[0] = 0x02; // bnr,nad,cid,chn=0; i-block(0x00) + if (send_chaining) { + real_cmd[0] |= 0x10; + } // put block number into the PCB real_cmd[0] |= iso14_pcb_blocknum; memcpy(real_cmd + 1, cmd, cmd_len); @@ -2245,7 +2248,7 @@ int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, void *data, uint8_t *res) { return 0; //DATA LINK ERROR } else{ // S-Block WTX - while((data_bytes[0] & 0xF2) == 0xF2) { + while(len && ((data_bytes[0] & 0xF2) == 0xF2)) { uint32_t save_iso14a_timeout = iso14a_get_timeout(); // temporarily increase timeout iso14a_set_timeout( MAX((data_bytes[1] & 0x3f) * save_iso14a_timeout, MAX_ISO14A_TIMEOUT) ); @@ -2263,32 +2266,34 @@ int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, void *data, uint8_t *res) { iso14a_set_timeout(save_iso14a_timeout); } - // if we received an I- or R(ACK)-Block with a block number equal to the - // current block number, toggle the current block number + // if we received an I- or R(ACK)-Block with a block number equal to the + // current block number, toggle the current block number if (len >= 3 // PCB+CRC = 3 bytes && ((data_bytes[0] & 0xC0) == 0 // I-Block || (data_bytes[0] & 0xD0) == 0x80) // R-Block with ACK bit set to 0 && (data_bytes[0] & 0x01) == iso14_pcb_blocknum) // equal block numbers - { - iso14_pcb_blocknum ^= 1; - } + { + iso14_pcb_blocknum ^= 1; + } // if we received I-block with chaining we need to send ACK and receive another block of data if (res) *res = data_bytes[0]; // crc check - if (len >=3 && !check_crc(CRC_14443_A, data_bytes, len)) { + if (len >= 3 && !check_crc(CRC_14443_A, data_bytes, len)) { return -1; } } - // cut frame byte - len -= 1; - // memmove(data_bytes, data_bytes + 1, len); - for (int i = 0; i < len; i++) - data_bytes[i] = data_bytes[i + 1]; + if (len) { + // cut frame byte + len -= 1; + // memmove(data_bytes, data_bytes + 1, len); + for (int i = 0; i < len; i++) + data_bytes[i] = data_bytes[i + 1]; + } return len; } @@ -2338,7 +2343,7 @@ void ReaderIso14443a(UsbCommand *c) { if ((param & ISO14A_APDU)) { uint8_t res; - arg0 = iso14_apdu(cmd, len, buf, &res); + arg0 = iso14_apdu(cmd, len, (param & ISO14A_SEND_CHAINING), buf, &res); cmd_send(CMD_ACK, arg0, res, 0, buf, sizeof(buf)); } diff --git a/armsrc/iso14443a.h b/armsrc/iso14443a.h index 7f979e531..a23b5d7c2 100644 --- a/armsrc/iso14443a.h +++ b/armsrc/iso14443a.h @@ -114,7 +114,7 @@ extern void ReaderTransmitPar(uint8_t *frame, uint16_t len, uint8_t *par, uint32 extern int ReaderReceive(uint8_t *receivedAnswer, uint8_t *par); extern void iso14443a_setup(uint8_t fpga_minor_mode); -extern int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, void *data, uint8_t *res); +extern int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, bool send_chaining, void *data, uint8_t *res); extern int iso14443a_select_card(uint8_t *uid_ptr, iso14a_card_select_t *resp_data, uint32_t *cuid_ptr, bool anticollision, uint8_t num_cascades, bool no_rats); extern int iso14443a_fast_select_card(uint8_t *uid_ptr, uint8_t num_cascades); extern void iso14a_set_trigger(bool enable); diff --git a/armsrc/legicrf.c b/armsrc/legicrf.c index 00d284926..958d3421a 100644 --- a/armsrc/legicrf.c +++ b/armsrc/legicrf.c @@ -61,7 +61,7 @@ static inline uint8_t rx_byte_from_fpga() { WDT_HIT(); // wait for byte be become available in rx holding register - if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { + if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { return AT91C_BASE_SSC->SSC_RHR; } } @@ -81,7 +81,7 @@ static inline uint8_t rx_byte_from_fpga() { // To reduce CPU time the amplitude is approximated by using linear functions: // am = MAX(ABS(i),ABS(q)) + 1/2*MIN(ABS(i),ABSq)) // -// Note: The SSC receiver is never synchronized the calculation my be performed +// Note: The SSC receiver is never synchronized the calculation may be performed // on a i/q pair from two subsequent correlations, but does not matter. static inline int32_t sample_power() { int32_t q = (int8_t)rx_byte_from_fpga(); q = ABS(q); @@ -100,7 +100,7 @@ static inline int32_t sample_power() { static inline bool rx_bit() { int32_t power; - for(size_t i = 0; i<5; ++i) { + for (size_t i = 0; i<5; ++i) { power = sample_power(); } @@ -120,12 +120,12 @@ static inline void tx_bit(bool bit) { // insert pause LOW(GPIO_SSC_DOUT); last_frame_end += RWD_TIME_PAUSE; - while(GET_TICKS < last_frame_end) { }; + while (GET_TICKS < last_frame_end) { }; HIGH(GPIO_SSC_DOUT); // return to high, wait for bit periode to end last_frame_end += (bit ? RWD_TIME_1 : RWD_TIME_0) - RWD_TIME_PAUSE; - while(GET_TICKS < last_frame_end) { }; + while (GET_TICKS < last_frame_end) { }; } //----------------------------------------------------------------------------- @@ -143,13 +143,13 @@ static void tx_frame(uint32_t frame, uint8_t len) { // wait for next tx timeslot last_frame_end += RWD_FRAME_WAIT; - while(GET_TICKS < last_frame_end) { }; + while (GET_TICKS < last_frame_end) { }; // backup ts for trace log uint32_t last_frame_start = last_frame_end; // transmit frame, MSB first - for(uint8_t i = 0; i < len; ++i) { + for (uint8_t i = 0; i < len; ++i) { bool bit = (frame >> i) & 0x01; tx_bit(bit ^ legic_prng_get_bit()); legic_prng_forward(1); @@ -158,7 +158,7 @@ static void tx_frame(uint32_t frame, uint8_t len) { // add pause to mark end of the frame LOW(GPIO_SSC_DOUT); last_frame_end += RWD_TIME_PAUSE; - while(GET_TICKS < last_frame_end) { }; + while (GET_TICKS < last_frame_end) { }; HIGH(GPIO_SSC_DOUT); // log @@ -173,19 +173,19 @@ static uint32_t rx_frame(uint8_t len) { // hold sampling until card is expected to respond last_frame_end += TAG_FRAME_WAIT; - while(GET_TICKS < last_frame_end) { }; + while (GET_TICKS < last_frame_end) { }; // backup ts for trace log uint32_t last_frame_start = last_frame_end; uint32_t frame = 0; - for(uint8_t i = 0; i < len; ++i) { + for (uint8_t i = 0; i < len; ++i) { frame |= (rx_bit() ^ legic_prng_get_bit()) << i; legic_prng_forward(1); // rx_bit runs only 95us, resync to TAG_BIT_PERIOD last_frame_end += TAG_BIT_PERIOD; - while(GET_TICKS < last_frame_end) { }; + while (GET_TICKS < last_frame_end) { }; } // log @@ -203,23 +203,23 @@ static bool rx_ack() { // hold sampling until card is expected to respond last_frame_end += TAG_FRAME_WAIT; - while(GET_TICKS < last_frame_end) { }; + while (GET_TICKS < last_frame_end) { }; // backup ts for trace log uint32_t last_frame_start = last_frame_end; uint32_t ack = 0; - for(uint8_t i = 0; i < TAG_WRITE_TIMEOUT; ++i) { + for (uint8_t i = 0; i < TAG_WRITE_TIMEOUT; ++i) { // sample bit ack = rx_bit(); legic_prng_forward(1); // rx_bit runs only 95us, resync to TAG_BIT_PERIOD last_frame_end += TAG_BIT_PERIOD; - while(GET_TICKS < last_frame_end) { }; + while (GET_TICKS < last_frame_end) { }; // check if it was an ACK - if(ack) { + if (ack) { break; } } @@ -282,7 +282,7 @@ static void init_reader(bool clear_mem) { // reserve a cardmem, meaning we can use the tracelog function in bigbuff easier. legic_mem = BigBuf_get_EM_addr(); - if(legic_mem) { + if (legic_mem) { memset(legic_mem, 0x00, LEGIC_CARD_MEMSIZE); } @@ -309,7 +309,7 @@ static uint32_t setup_phase(uint8_t iv) { // Switch on carrier and let the card charge for 5ms. last_frame_end += 7500; - while(GET_TICKS < last_frame_end) { }; + while (GET_TICKS < last_frame_end) { }; legic_prng_init(0); tx_frame(iv, 7); @@ -359,7 +359,7 @@ static int16_t read_byte(uint16_t index, uint8_t cmd_sz) { // check received against calculated crc uint8_t calc_crc = calc_crc4(cmd, cmd_sz, byte); - if(calc_crc != crc) { + if (calc_crc != crc) { Dbprintf("!!! crc mismatch: %x != %x !!!", calc_crc, crc); return -1; } @@ -399,15 +399,15 @@ void LegicRfInfo(void) { // establish shared secret and detect card type uint8_t card_type = setup_phase(0x01); - if(init_card(card_type, &card) != 0) { + if (init_card(card_type, &card) != 0) { cmd_send(CMD_ACK, 0, 0, 0, 0, 0); goto OUT; } // read UID - for(uint8_t i = 0; i < sizeof(card.uid); ++i) { + for (uint8_t i = 0; i < sizeof(card.uid); ++i) { int16_t byte = read_byte(i, card.cmdsize); - if(byte == -1) { + if (byte == -1) { cmd_send(CMD_ACK, 0, 0, 0, 0, 0); goto OUT; } @@ -417,7 +417,7 @@ void LegicRfInfo(void) { // read MCC and check against UID int16_t mcc = read_byte(4, card.cmdsize); int16_t calc_mcc = CRC8Legic(card.uid, 4);; - if(mcc != calc_mcc) { + if (mcc != calc_mcc) { cmd_send(CMD_ACK, 0, 0, 0, 0, 0); goto OUT; } @@ -436,19 +436,19 @@ void LegicRfReader(uint16_t offset, uint16_t len, uint8_t iv) { // establish shared secret and detect card type uint8_t card_type = setup_phase(iv); - if(init_card(card_type, &card) != 0) { + if (init_card(card_type, &card) != 0) { cmd_send(CMD_ACK, 0, 0, 0, 0, 0); goto OUT; } // do not read beyond card memory - if(len + offset > card.cardsize) { + if (len + offset > card.cardsize) { len = card.cardsize - offset; } - for(uint16_t i = 0; i < len; ++i) { + for (uint16_t i = 0; i < len; ++i) { int16_t byte = read_byte(offset + i, card.cmdsize); - if(byte == -1) { + if (byte == -1) { cmd_send(CMD_ACK, 0, 0, 0, 0, 0); goto OUT; } @@ -468,26 +468,26 @@ void LegicRfWriter(uint16_t offset, uint16_t len, uint8_t iv, uint8_t *data) { init_reader(false); // uid is not writeable - if(offset <= WRITE_LOWERLIMIT) { + if (offset <= WRITE_LOWERLIMIT) { cmd_send(CMD_ACK, 0, 0, 0, 0, 0); goto OUT; } // establish shared secret and detect card type uint8_t card_type = setup_phase(iv); - if(init_card(card_type, &card) != 0) { + if (init_card(card_type, &card) != 0) { cmd_send(CMD_ACK, 0, 0, 0, 0, 0); goto OUT; } // do not write beyond card memory - if(len + offset > card.cardsize) { + if (len + offset > card.cardsize) { len = card.cardsize - offset; } // write in reverse order, only then is DCF (decremental field) writable - while(len-- > 0 && !BUTTON_PRESS()) { - if(!write_byte(len + offset, data[len], card.addrsize)) { + while (len-- > 0 && !BUTTON_PRESS()) { + if (!write_byte(len + offset, data[len], card.addrsize)) { Dbprintf("operation failed | %02X | %02X | %02X", len + offset, len, data[len]); cmd_send(CMD_ACK, 0, 0, 0, 0, 0); goto OUT; diff --git a/armsrc/legicrfsim.c b/armsrc/legicrfsim.c index 1816a29ca..86448275f 100644 --- a/armsrc/legicrfsim.c +++ b/armsrc/legicrfsim.c @@ -46,7 +46,7 @@ static uint32_t last_frame_end; /* ts of last bit of previews rx or tx frame */ #define RWD_TIME_PAUSE 4 /* 18.9us */ #define RWD_TIME_1 21 /* RWD_TIME_PAUSE 18.9us off + 80.2us on = 99.1us */ #define RWD_TIME_0 13 /* RWD_TIME_PAUSE 18.9us off + 42.4us on = 61.3us */ -#define RWD_CMD_TIMEOUT 40 /* 40 * 99.1us (arbitrary value) */ +#define RWD_CMD_TIMEOUT 120 /* 120 * 99.1us (arbitrary value) */ #define RWD_MIN_FRAME_LEN 6 /* Shortest frame is 6 bits */ #define RWD_MAX_FRAME_LEN 23 /* Longest frame is 23 bits */ @@ -59,8 +59,8 @@ static uint32_t last_frame_end; /* ts of last bit of previews rx or tx frame */ // Returns true if a pulse/pause is received within timeout static inline bool wait_for(bool value, const uint32_t timeout) { - while((bool)(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_DIN) != value) { - if(GetCountSspClk() > timeout) { + while ((bool)(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_DIN) != value) { + if (GetCountSspClk() > timeout) { return false; } } @@ -81,12 +81,12 @@ static inline int8_t rx_bit() { uint32_t bit_start = last_frame_end; // wait for pause to end - if(!wait_for(RWD_PULSE, bit_start + RWD_TIME_1*3/2)) { + if (!wait_for(RWD_PULSE, bit_start + RWD_TIME_1*3/2)) { return -1; } // wait for next pause - if(!wait_for(RWD_PAUSE, bit_start + RWD_TIME_1*3/2)) { + if (!wait_for(RWD_PAUSE, bit_start + RWD_TIME_1*3/2)) { return -1; } @@ -94,7 +94,7 @@ static inline int8_t rx_bit() { last_frame_end = GetCountSspClk(); // check for code violation (bit to short) - if(last_frame_end - bit_start < RWD_TIME_PAUSE) { + if (last_frame_end - bit_start < RWD_TIME_PAUSE) { return -1; } @@ -122,7 +122,7 @@ static inline int8_t rx_bit() { static inline void tx_bit(bool bit) { LED_C_ON(); - if(bit) { + if (bit) { // modulate subcarrier HIGH(GPIO_SSC_DOUT); } else { @@ -132,7 +132,7 @@ static inline void tx_bit(bool bit) { // wait for tx timeslot to end last_frame_end += TAG_BIT_PERIOD; - while(GetCountSspClk() < last_frame_end) { }; + while (GetCountSspClk() < last_frame_end) { }; LED_C_OFF(); } @@ -150,13 +150,13 @@ static void tx_frame(uint32_t frame, uint8_t len) { // wait for next tx timeslot last_frame_end += TAG_FRAME_WAIT; legic_prng_forward(TAG_FRAME_WAIT/TAG_BIT_PERIOD - 1); - while(GetCountSspClk() < last_frame_end) { }; + while (GetCountSspClk() < last_frame_end) { }; // backup ts for trace log uint32_t last_frame_start = last_frame_end; // transmit frame, MSB first - for(uint8_t i = 0; i < len; ++i) { + for (uint8_t i = 0; i < len; ++i) { bool bit = (frame >> i) & 0x01; tx_bit(bit ^ legic_prng_get_bit()); legic_prng_forward(1); @@ -174,7 +174,7 @@ static void tx_ack() { // wait for ack timeslot last_frame_end += TAG_ACK_WAIT; legic_prng_forward(TAG_ACK_WAIT/TAG_BIT_PERIOD - 1); - while(GetCountSspClk() < last_frame_end) { }; + while (GetCountSspClk() < last_frame_end) { }; // backup ts for trace log uint32_t last_frame_start = last_frame_end; @@ -206,19 +206,19 @@ static int32_t rx_frame(uint8_t *len) { last_frame_end -= 2; // wait for first pause (start of frame) - for(uint8_t i = 0; true; ++i) { + for (uint8_t i = 0; true; ++i) { // increment prng every TAG_BIT_PERIOD last_frame_end += TAG_BIT_PERIOD; legic_prng_forward(1); // if start of frame was received exit delay loop - if(wait_for(RWD_PAUSE, last_frame_end)) { + if (wait_for(RWD_PAUSE, last_frame_end)) { last_frame_end = GetCountSspClk(); break; } // check for code violation - if(i > RWD_CMD_TIMEOUT) { + if (i > RWD_CMD_TIMEOUT) { return -1; } } @@ -227,19 +227,19 @@ static int32_t rx_frame(uint8_t *len) { uint32_t last_frame_start = last_frame_end; // receive frame - for(*len = 0; true; ++(*len)) { + for (*len = 0; true; ++(*len)) { // receive next bit LED_B_ON(); int8_t bit = rx_bit(); LED_B_OFF(); // check for code violation and to short / long frame - if((bit < 0) && ((*len < RWD_MIN_FRAME_LEN) || (*len > RWD_MAX_FRAME_LEN))) { + if ((bit < 0) && ((*len < RWD_MIN_FRAME_LEN) || (*len > RWD_MAX_FRAME_LEN))) { return -1; } // check for code violation caused by end of frame - if(bit < 0) { + if (bit < 0) { break; } @@ -256,7 +256,6 @@ static int32_t rx_frame(uint8_t *len) { // log uint8_t cmdbytes[] = {*len, BYTEx(frame, 0), BYTEx(frame, 1), BYTEx(frame, 2)}; LogTrace(cmdbytes, sizeof(cmdbytes), last_frame_start, last_frame_end, NULL, true); - return frame; } @@ -267,7 +266,7 @@ static int32_t rx_frame(uint8_t *len) { static int32_t init_card(uint8_t cardtype, legic_card_select_t *p_card) { p_card->tagtype = cardtype; - switch(p_card->tagtype) { + switch (p_card->tagtype) { case 0: p_card->cmdsize = 6; p_card->addrsize = 5; @@ -338,7 +337,7 @@ static int32_t setup_phase(legic_card_select_t *p_card) { // wait for iv int32_t iv = rx_frame(&len); - if((len != 7) || (iv < 0)) { + if ((len != 7) || (iv < 0)) { return -1; } @@ -346,7 +345,7 @@ static int32_t setup_phase(legic_card_select_t *p_card) { legic_prng_init(iv); // reply with card type - switch(p_card->tagtype) { + switch (p_card->tagtype) { case 0: tx_frame(0x0D, 6); break; @@ -360,12 +359,12 @@ static int32_t setup_phase(legic_card_select_t *p_card) { // wait for ack int32_t ack = rx_frame(&len); - if((len != 6) || (ack < 0)) { + if ((len != 6) || (ack < 0)) { return -1; } // validate data - switch(p_card->tagtype) { + switch (p_card->tagtype) { case 0: if(ack != 0x19) return -1; break; @@ -399,12 +398,12 @@ static int32_t connected_phase(legic_card_select_t *p_card) { // wait for command int32_t cmd = rx_frame(&len); - if(cmd < 0) { + if (cmd < 0) { return -1; } // check if command is LEGIC_READ - if(len == p_card->cmdsize) { + if (len == p_card->cmdsize) { // prepare data uint8_t byte = legic_mem[cmd >> 1]; uint8_t crc = calc_crc4(cmd, p_card->cmdsize, byte); @@ -416,7 +415,7 @@ static int32_t connected_phase(legic_card_select_t *p_card) { } // check if command is LEGIC_WRITE - if(len == p_card->cmdsize + 8 + 4) { + if (len == p_card->cmdsize + 8 + 4) { // decode data uint16_t mask = (1 << p_card->addrsize) - 1; uint16_t addr = (cmd >> 1) & mask; @@ -425,7 +424,7 @@ static int32_t connected_phase(legic_card_select_t *p_card) { // check received against calculated crc uint8_t calc_crc = calc_crc4(addr << 1, p_card->cmdsize, byte); - if(calc_crc != crc) { + if (calc_crc != crc) { Dbprintf("!!! crc mismatch: %x != %x !!!", calc_crc, crc); return -1; } @@ -453,7 +452,7 @@ void LegicRfSimulate(uint8_t cardtype) { init_tag(); // verify command line input - if(init_card(cardtype, &card) != 0) { + if (init_card(cardtype, &card) != 0) { DbpString("Unknown tagtype."); goto OUT; } @@ -464,17 +463,17 @@ void LegicRfSimulate(uint8_t cardtype) { WDT_HIT(); // wait for carrier, restart after timeout - if(!wait_for(RWD_PULSE, GetCountSspClk() + TAG_BIT_PERIOD)) { + if (!wait_for(RWD_PULSE, GetCountSspClk() + TAG_BIT_PERIOD)) { continue; } // wait for connection, restart on error - if(setup_phase(&card)) { + if (setup_phase(&card)) { continue; } // conection is established, process commands until one fails - while(!connected_phase(&card)) { + while (!connected_phase(&card)) { WDT_HIT(); } } diff --git a/armsrc/lfops.c b/armsrc/lfops.c index e690714df..96abd9b99 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -80,7 +80,7 @@ void setT55xxConfig(uint8_t arg0, t55xx_config *c) { printT55xxConfig(); -#if WITH_FLASH +#ifdef WITH_FLASH // shall persist to flashmem if (arg0 == 0) { return; @@ -119,7 +119,7 @@ t55xx_config* getT55xxConfig(void) { } void loadT55xxConfig(void) { -#if WITH_FLASH +#ifdef WITH_FLASH if (!FlashInit()) { return; } @@ -598,9 +598,11 @@ void SimulateTagLowFrequencyEx(int period, int gap, int ledcontrol, int numcycle AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT | GPIO_SSC_CLK; AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; AT91C_BASE_PIOA->PIO_ODR = GPIO_SSC_CLK; + + uint8_t check = 1; for(;;) { - + if ( numcycles > -1 ) { if ( x != numcycles ) { ++x; @@ -616,9 +618,11 @@ void SimulateTagLowFrequencyEx(int period, int gap, int ledcontrol, int numcycle // used as a simple detection of a reader field? while (!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) { WDT_HIT(); - if ( usb_poll_validate_length() || BUTTON_PRESS() ) - goto OUT; - } + if ( !check ) { + if ( usb_poll_validate_length() || BUTTON_PRESS() ) + goto OUT; + } + ++check; } if (buf[i]) OPEN_COIL(); @@ -628,9 +632,11 @@ void SimulateTagLowFrequencyEx(int period, int gap, int ledcontrol, int numcycle //wait until SSC_CLK goes LOW while (AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK) { WDT_HIT(); - //if ( usb_poll_validate_length() || BUTTON_PRESS() ) - if ( BUTTON_PRESS() ) - goto OUT; + if ( !check ) { + if ( usb_poll_validate_length() || BUTTON_PRESS() ) + goto OUT; + } + ++check; } i++; @@ -1489,11 +1495,22 @@ void T55xxWriteBlock(uint32_t Data, uint8_t Block, uint32_t Pwd, uint8_t arg) { // Read one card block in page [page] void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd) { LED_A_ON(); - bool PwdMode = arg0 & 0x1; - uint8_t Page = (arg0 & 0x2) >> 1; - uint32_t i = 0; - bool RegReadMode = (Block == 0xFF);//regular read mode + bool PwdMode = arg0 & 0x1; + uint8_t Page = ( arg0 & 0x2 ) >> 1; + bool brute_mem = arg0 & 0x4; + uint32_t i = 0; + + // regular read mode + bool RegReadMode = (Block == 0xFF); + + uint8_t start_wait = 4; + size_t samples = 12000; + if ( brute_mem ) { + start_wait = 0; + samples = 1024; + } + //clear buffer now so it does not interfere with timing later BigBuf_Clear_keep_EM(); @@ -1505,7 +1522,8 @@ void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd) { // Set up FPGA, 125kHz to power up the tag LFSetupFPGAForADC(95, true); // make sure tag is fully powered up... - WaitMS(4); + WaitMS(start_wait); + // Trigger T55x7 Direct Access Mode with start gap FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); WaitUS(t_config.start_gap); @@ -1529,17 +1547,118 @@ void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd) { // Turn field on to read the response // 137*8 seems to get to the start of data pretty well... - // but we want to go past the start and let the repeating data settle in... - TurnReadLFOn(210*8); + // but we want to go past the start and let the repeating data settle in... + TurnReadLFOn(200*8); // Acquisition // Now do the acquisition - DoPartialAcquisition(0, true, 12000, 0); + DoPartialAcquisition(0, true, samples, 0); // Turn the field off - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off - cmd_send(CMD_ACK,0,0,0,0,0); - LED_A_OFF(); + if ( !brute_mem ) { + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + cmd_send(CMD_ACK,0,0,0,0,0); + LED_A_OFF(); + } +} + +void T55xx_ChkPwds() { + + DbpString("[+] T55XX Check pwds using flashmemory starting"); + + uint8_t ret = 0; + // First get baseline and setup LF mode. + // tends to mess up BigBuf + uint8_t *buf = BigBuf_get_addr(); + + uint32_t b1, baseline = 0; + + // collect baseline for failed attempt + uint8_t x = 32; + while (x--) { + b1 = 0; + T55xxReadBlock(4, 1, 0); + for (uint16_t j=0; j < 1024; ++j) + b1 += buf[j]; + + b1 *= b1; + b1 >>= 8; + baseline += b1; + } + + baseline >>= 5; + Dbprintf("[=] Baseline determined [%u]", baseline); + + + uint8_t *pwds = BigBuf_get_EM_addr(); + uint16_t pwdCount = 0; + uint32_t candidate = 0; + +#ifdef WITH_FLASH + bool use_flashmem = true; + if ( use_flashmem ) { + BigBuf_Clear_EM(); + uint16_t isok = 0; + uint8_t counter[2] = {0x00, 0x00}; + isok = Flash_ReadData(DEFAULT_T55XX_KEYS_OFFSET, counter, sizeof(counter) ); + if ( isok != sizeof(counter) ) + goto OUT; + + pwdCount = counter[1] << 8 | counter[0]; + + if ( pwdCount == 0 && pwdCount == 0xFFFF) + goto OUT; + + isok = Flash_ReadData(DEFAULT_T55XX_KEYS_OFFSET+2, pwds, pwdCount * 4); + if ( isok != pwdCount * 4 ) + goto OUT; + + Dbprintf("[=] Password dictionary count %d ", pwdCount); + } +#endif + + uint32_t pwd = 0, curr = 0, prev = 0; + for (uint16_t i =0; i< pwdCount; ++i) { + + if (BUTTON_PRESS() && !usb_poll_validate_length()) { + goto OUT; + } + + pwd = bytes_to_num(pwds + i * 4, 4); + + + T55xxReadBlock(5, 0, pwd); + + // calc mean of BigBuf 1024 samples. + uint32_t sum = 0; + for (uint16_t j=0; j<1024; ++j) { + sum += buf[j]; + } + + sum *= sum; + sum >>= 8; + + int32_t tmp = (sum - baseline); + curr = ABS(tmp); + + Dbprintf("[=] Pwd %08X | ABS %u", pwd, curr ); + + if ( curr > prev ) { + + + Dbprintf("[=] --> ABS %u Candidate %08X <--", curr, pwd ); + candidate = pwd; + prev = curr; + } + } + + if ( candidate ) + ret = 1; + +OUT: + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + cmd_send(CMD_ACK,ret,candidate,0,0,0); + LEDsoff(); } void T55xxWakeUp(uint32_t Pwd){ @@ -1970,7 +2089,6 @@ void EM4xWriteWord(uint32_t flag, uint32_t data, uint32_t pwd) { //Wait 20ms for write to complete? WaitMS(7); - //Capture response if one exists DoPartialAcquisition(20, true, 6000, 1000); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); @@ -1994,7 +2112,7 @@ This triggers a COTAG tag to response */ void Cotag(uint32_t arg0) { #ifndef OFF -# define OFF { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); WaitUS(2035); } +# define OFF(x) { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); WaitUS((x)); } #endif #ifndef ON # define ON(x) { FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); WaitUS((x)); } @@ -2003,29 +2121,15 @@ void Cotag(uint32_t arg0) { LED_A_ON(); - // Switching to LF image on FPGA. This might empty BigBuff - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - + LFSetupFPGAForADC(89, true); + //clear buffer now so it does not interfere with timing later BigBuf_Clear_ext(false); - // Set up FPGA, 132kHz to power up the tag - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 89); - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - - // Connect the A/D to the peak-detected low-frequency path. - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); - - // Now set up the SSC to get the ADC samples that are now streaming at us. - FpgaSetupSsc(); - - // start clock - 1.5ticks is 1us - StartTicks(); - //send COTAG start pulse - ON(740) OFF - ON(3330) OFF - ON(740) OFF + ON(740) OFF(2035) + ON(3330) OFF(2035) + ON(740) OFF(2035) ON(1000) switch(rawsignal) { diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index 22171e2c3..96963d389 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -117,21 +117,21 @@ void LFSetupFPGAForADC(int divisor, bool lf_field) { * @return the number of bits occupied by the samples. */ uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averaging, int trigger_threshold, bool silent, int bufsize, uint32_t cancel_after) { - //bigbuf, to hold the aquired raw data signal + uint8_t *dest = BigBuf_get_addr(); bufsize = (bufsize > 0 && bufsize < BigBuf_max_traceLen()) ? bufsize : BigBuf_max_traceLen(); - if (bits_per_sample < 1) bits_per_sample = 1; if (bits_per_sample > 8) bits_per_sample = 8; if (decimation < 1) decimation = 1; - // Use a bit stream to handle the output + // use a bit stream to handle the output BitstreamOut data = { dest , 0, 0}; int sample_counter = 0; uint8_t sample = 0; - //If we want to do averaging + + // if we want to do averaging uint32_t sample_sum =0 ; uint32_t sample_total_numbers = 0; uint32_t sample_total_saved = 0; @@ -139,13 +139,13 @@ uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averag while (!BUTTON_PRESS() && !usb_poll_validate_length() ) { WDT_HIT(); - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = 0x43; - LED_D_ON(); - } + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + + // Testpoint 8 (TP8) can be used to trigger oscilliscope LED_D_OFF(); + // threshold either high or low values 128 = center 0. if trigger = 178 if ((trigger_threshold > 0) && (sample < (trigger_threshold + 128)) && (sample > (128 - trigger_threshold))) { if (cancel_after > 0) { @@ -162,24 +162,26 @@ uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averag if (averaging) sample_sum += sample; - //Check decimation + // check decimation if (decimation > 1) { sample_counter++; if (sample_counter < decimation) continue; sample_counter = 0; } - //Averaging + // averaging if (averaging && decimation > 1) { sample = sample_sum / decimation; sample_sum =0; } - //Store the sample + // store the sample sample_total_saved ++; - if (bits_per_sample == 8){ + if (bits_per_sample == 8) { dest[sample_total_saved-1] = sample; - data.numbits = sample_total_saved << 3;//Get the return value correct + + // Get the return value correct + data.numbits = sample_total_saved << 3; if (sample_total_saved >= bufsize) break; } else { @@ -190,9 +192,8 @@ uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averag if (bits_per_sample > 4) pushBit(&data, sample & 0x08); if (bits_per_sample > 5) pushBit(&data, sample & 0x04); if (bits_per_sample > 6) pushBit(&data, sample & 0x02); - //Not needed, 8bps is covered above - //if (bits_per_sample > 7) pushBit(&data, sample & 0x01); - if ((data.numbits >> 3) +1 >= bufsize) break; + + if ((data.numbits >> 3) + 1 >= bufsize) break; } } } @@ -285,10 +286,8 @@ void doT55x7Acquisition(size_t sample_size) { while(!BUTTON_PRESS() && !usb_poll_validate_length() && skipCnt < 1000 && (i < bufsize) ) { WDT_HIT(); - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = 0x43; //43 - LED_D_ON(); - } + + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { curSample = (uint8_t)AT91C_BASE_SSC->SSC_RHR; LED_D_OFF(); @@ -352,11 +351,7 @@ void doCotagAcquisition(size_t sample_size) { while (!BUTTON_PRESS() && !usb_poll_validate_length() && (i < bufsize) && (noise_counter < (COTAG_T1 << 1)) ) { WDT_HIT(); - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = 0x43; - LED_D_ON(); - } - + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR; LED_D_OFF(); @@ -406,12 +401,8 @@ uint32_t doCotagAcquisitionManchester() { uint16_t noise_counter = 0; while (!BUTTON_PRESS() && !usb_poll_validate_length() && (sample_counter < bufsize) && (noise_counter < (COTAG_T1 << 1)) ) { - WDT_HIT(); - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = 0x43; - LED_D_ON(); - } - + WDT_HIT(); + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR; LED_D_OFF(); diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 3e1967b4e..6b10ddd0d 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -1259,7 +1259,6 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da LED_A_ON(); if ( firstchunk ) { - clear_trace(); set_tracing(false); @@ -1458,26 +1457,31 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da } // end loop sectors } // end loop keys } // end loop strategy 2 -OUT: +OUT: LEDsoff(); crypto1_destroy(pcs); // All keys found, send to client, or last keychunk from client if (foundkeys == allkeys || lastchunk ) { - + uint64_t foo = 0; + for (uint8_t m = 0; m < 64; m++) { + foo |= ((uint64_t)(found[m] & 1) << m); + } + uint16_t bar = 0; - for (uint8_t m = 0; m < 64; ++m) - foo |= (found[m] << m); - for (uint8_t m=64; m < sizeof(found); ++m) - bar |= (found[m] << (m-64)); - + uint8_t j = 0; + for (uint8_t m=64; m < sizeof(found); m++) { + bar |= ((uint16_t)(found[m] & 1) << j++); + } + uint8_t *tmp = BigBuf_malloc(480+10); memcpy(tmp, k_sector, sectorcnt * sizeof(sector_t) ); num_to_bytes(foo, 8, tmp+480); tmp[488] = bar & 0xFF; tmp[489] = bar >> 8 & 0xFF; + cmd_send(CMD_ACK, foundkeys, 0, 0, tmp, 480+10); set_tracing(false); diff --git a/armsrc/optimized_cipher.c b/armsrc/optimized_cipher.c index 36b25f593..223d73fea 100644 --- a/armsrc/optimized_cipher.c +++ b/armsrc/optimized_cipher.c @@ -22,7 +22,7 @@ * * This is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. + * by the Free Software Foundation, or, at your option, any later version. * * This file is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/client/Makefile b/client/Makefile index 4f7168fa0..0b19d4599 100644 --- a/client/Makefile +++ b/client/Makefile @@ -299,29 +299,29 @@ lualibs/mf_default_keys.lua : default_keys.dic clean: $(RM) $(CLEAN) - cd ../liblua && make clean - cd $(JANSSONLIBPATH) && make clean - cd $(MBEDTLSLIBPATH) && make clean - cd $(CBORLIBPATH) && make clean + cd ../liblua && $(MAKE) clean + cd $(JANSSONLIBPATH) && $(MAKE) clean + cd $(MBEDTLSLIBPATH) && $(MAKE) clean + cd $(CBORLIBPATH) && $(MAKE) clean tarbin: $(BINS) $(TAR) $(TARFLAGS) ../proxmark3-$(platform)-bin.tar $(BINS:%=client/%) $(WINBINS:%=client/%) lua_build: @echo Compiling liblua, using platform $(LUAPLATFORM) - cd ../liblua && make $(LUAPLATFORM) + cd ../liblua && $(MAKE) $(LUAPLATFORM) jansson_build: @echo Compiling jansson - cd $(JANSSONLIBPATH) && make all + cd $(JANSSONLIBPATH) && $(MAKE) all mbedtls_build: @echo Compiling mbedtls - cd $(MBEDTLSLIBPATH) && make all + cd $(MBEDTLSLIBPATH) && $(MAKE) all cbor_build: @echo Compiling tinycbor - cd $(CBORLIBPATH) && make all + cd $(CBORLIBPATH) && $(MAKE) all .PHONY: all clean diff --git a/client/cmddata.c b/client/cmddata.c index a9f58b962..65fd0d829 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -1786,7 +1786,7 @@ int Cmdbin2hex(const char *Cmd) { //Number of digits supplied as argument size_t length = en - bg + 1; size_t bytelen = (length+7) / 8; - uint8_t* arr = (uint8_t *) malloc(bytelen); + uint8_t* arr = (uint8_t *) calloc(bytelen, sizeof(uint8_t)); memset(arr, 0, bytelen); BitstreamOut bout = { arr, 0, 0 }; diff --git a/client/cmdflashmem.c b/client/cmdflashmem.c index 6361d48e3..d3aaff19e 100644 --- a/client/cmdflashmem.c +++ b/client/cmdflashmem.c @@ -7,6 +7,8 @@ //----------------------------------------------------------------------------- // Proxmark3 RDV40 Flash memory commands //----------------------------------------------------------------------------- +#ifdef WITH_FLASH + #include "cmdflashmem.h" #include "mbedtls/rsa.h" @@ -604,3 +606,5 @@ int CmdHelp(const char *Cmd) { CmdsHelp(CommandTable); return 0; } + +#endif \ No newline at end of file diff --git a/client/cmdflashmem.h b/client/cmdflashmem.h index 9f71a4ce0..ee661bf18 100644 --- a/client/cmdflashmem.h +++ b/client/cmdflashmem.h @@ -8,6 +8,8 @@ // Proxmark3 RDV40 Flash memory commands //----------------------------------------------------------------------------- +#ifdef WITH_FLASH + #ifndef CMDFLASHMEM_H__ #define CMDFLASHMEM_H__ @@ -38,4 +40,6 @@ extern int CmdFlashMemLoad(const char* cmd); extern int CmdFlashMemSave(const char* cmd); extern int CmdFlashMemWipe(const char *Cmd); extern int CmdFlashMemInfo(const char *Cmd); +#endif + #endif \ No newline at end of file diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index 43832e2cf..9140a3502 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -1,6 +1,6 @@ //----------------------------------------------------------------------------- // Copyright (C) 2010 iZsh , Hagen Fritsch -// 2011, 2017 Merlok +// 2011, 2017 - 2019 Merlok // 2014, Peter Fillmore // 2015, 2016, 2017 Iceman // @@ -12,6 +12,8 @@ //----------------------------------------------------------------------------- #include "cmdhf14a.h" +bool APDUInFramingEnable = true; + static int CmdHelp(const char *Cmd); static int waitCmd(uint8_t iLen); @@ -147,6 +149,10 @@ char* getTagInfo(uint8_t uid) { return manufactureMapping[len-1].desc; } +// iso14a apdu input frame length +static uint16_t frameLength = 0; +uint16_t atsFSC[] = {16, 24, 32, 40, 48, 64, 96, 128, 256}; + int usage_hf_14a_sim(void) { // PrintAndLogEx(NORMAL, "\n Emulating ISO/IEC 14443 type A tag with 4,7 or 10 byte UID\n"); PrintAndLogEx(NORMAL, "\n Emulating ISO/IEC 14443 type A tag with 4,7 byte UID\n"); @@ -486,10 +492,7 @@ int CmdHF14AInfo(const char *Cmd) { (tb1 ? "" : " NOT"), (tc1 ? "" : " NOT"), fsci, - fsci < 5 ? (fsci - 2) * 8 : - fsci < 8 ? (fsci - 3) * 32 : - fsci == 8 ? 256 : - -1 + fsci < sizeof(atsFSC) ? atsFSC[fsci] : -1 ); } pos = 2; @@ -836,15 +839,90 @@ int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leav return 0; } -int CmdExchangeAPDU(uint8_t *datain, int datainlen, bool activateField, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, bool *chaining) { - uint16_t cmdc = 0; +int SelectCard14443_4(bool disconnect, iso14a_card_select_t *card) { + UsbCommand resp; - *chaining = false; + frameLength = 0; + + if (card) + memset(card, 0, sizeof(iso14a_card_select_t)); - if (activateField) { - cmdc |= ISO14A_CONNECT; + DropField(); + + // Anticollision + SELECT card + UsbCommand ca = {CMD_READER_ISO_14443a, {ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0}}; + SendCommand(&ca); + if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { + PrintAndLogEx(ERR, "Proxmark connection timeout."); + return 1; } + // check result + if (resp.arg[0] == 0) { + PrintAndLogEx(ERR, "No card in field."); + return 1; + } + + if (resp.arg[0] != 1 && resp.arg[0] != 2) { + PrintAndLogEx(ERR, "Card not in iso14443-4. res=%d.", resp.arg[0]); + return 1; + } + + if (resp.arg[0] == 2) { // 0: couldn't read, 1: OK, with ATS, 2: OK, no ATS, 3: proprietary Anticollision + // get ATS + UsbCommand cr = {CMD_READER_ISO_14443a, {ISO14A_RAW | ISO14A_APPEND_CRC | ISO14A_NO_DISCONNECT, 2, 0}}; + uint8_t rats[] = { 0xE0, 0x80 }; // FSDI=8 (FSD=256), CID=0 + memcpy(cr.d.asBytes, rats, 2); + SendCommand(&cr); + if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { + PrintAndLogEx(ERR, "Proxmark connection timeout."); + return 1; + } + + if (resp.arg[0] <= 0) { // ats_len + PrintAndLogEx(ERR, "Can't get ATS."); + return 1; + } + + // get frame length from ATS in data field + if (resp.arg[0] > 1) { + uint8_t fsci = resp.d.asBytes[1] & 0x0f; + if (fsci < sizeof(atsFSC)) + frameLength = atsFSC[fsci]; + } + } else { + // get frame length from ATS in card data structure + iso14a_card_select_t *vcard = (iso14a_card_select_t *) resp.d.asBytes; + if (vcard->ats_len > 1) { + uint8_t fsci = vcard->ats[1] & 0x0f; + if (fsci < sizeof(atsFSC)) + frameLength = atsFSC[fsci]; + } + + if (card) + memcpy(card, vcard, sizeof(iso14a_card_select_t)); + } + + if (disconnect) + DropField(); + + return 0; +} + +int CmdExchangeAPDU(bool chainingin, uint8_t *datain, int datainlen, bool activateField, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, bool *chainingout) { + *chainingout = false; + + if (activateField) { + // select with no disconnect and set frameLength + int selres = SelectCard14443_4(false, NULL); + if (selres) + return selres; + } + + uint16_t cmdc = 0; + if (chainingin) + cmdc = ISO14A_SEND_CHAINING; + // "Command APDU" length should be 5+255+1, but javacard's APDU buffer might be smaller - 133 bytes // https://stackoverflow.com/questions/32994936/safe-max-java-card-apdu-data-command-and-respond-size // here length USB_CMD_DATA_SIZE=512 @@ -856,18 +934,6 @@ int CmdExchangeAPDU(uint8_t *datain, int datainlen, bool activateField, uint8_t uint8_t *recv; UsbCommand resp; - if (activateField) { - if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { - PrintAndLogEx(ERR, "APDU: Proxmark connection timeout."); - return 1; - } - if (resp.arg[0] != 1) { - PrintAndLogEx(ERR, "APDU: Proxmark error %d.", resp.arg[0]); - DropField(); - return 1; - } - } - if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { recv = resp.d.asBytes; int iLen = resp.arg[0]; @@ -883,13 +949,20 @@ int CmdExchangeAPDU(uint8_t *datain, int datainlen, bool activateField, uint8_t return 2; } + // I-block ACK + if ((res & 0xf2) == 0xa2) { + *dataoutlen = 0; + *chainingout = true; + return 0; + } + if(!iLen) { PrintAndLogEx(ERR, "APDU: No APDU response."); return 1; } // check apdu length - if (iLen < 4 && iLen >= 0) { + if (iLen < 2 && iLen >= 0) { PrintAndLogEx(ERR, "APDU: Small APDU response. Len=%d", iLen); return 2; } @@ -904,7 +977,7 @@ int CmdExchangeAPDU(uint8_t *datain, int datainlen, bool activateField, uint8_t // chaining if ((res & 0x10) != 0) { - *chaining = true; + *chainingout = true; } // CRC Check @@ -923,12 +996,57 @@ int CmdExchangeAPDU(uint8_t *datain, int datainlen, bool activateField, uint8_t int ExchangeAPDU14a(uint8_t *datain, int datainlen, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen) { *dataoutlen = 0; bool chaining = false; - - int res = CmdExchangeAPDU(datain, datainlen, activateField, dataout, maxdataoutlen, dataoutlen, &chaining); + int res; + // 3 byte here - 1b framing header, 2b crc16 + if (APDUInFramingEnable && + ( (frameLength && (datainlen > frameLength - 3)) || (datainlen > USB_CMD_DATA_SIZE - 3)) ) { + int clen = 0; + + bool vActivateField = activateField; + + do { + int vlen = MIN(frameLength - 3, datainlen - clen); + bool chainBlockNotLast = ((clen + vlen) < datainlen); + + *dataoutlen = 0; + res = CmdExchangeAPDU(chainBlockNotLast, &datain[clen], vlen, vActivateField, dataout, maxdataoutlen, dataoutlen, &chaining); + if (res) { + if (!leaveSignalON) + DropField(); + + return 200; + } + + // check R-block ACK + if ((*dataoutlen == 0) && (*dataoutlen != 0 || chaining != chainBlockNotLast)) { + if (!leaveSignalON) + DropField(); + + return 201; + } + + clen += vlen; + vActivateField = false; + if (*dataoutlen) { + if (clen != datainlen) + PrintAndLogEx(WARNING, "APDU: I-block/R-block sequence error. Data len=%d, Sent=%d, Last packet len=%d", datainlen, clen, *dataoutlen); + break; + } + } while (clen < datainlen); + } else { + res = CmdExchangeAPDU(false, datain, datainlen, activateField, dataout, maxdataoutlen, dataoutlen, &chaining); + if (res) { + if (!leaveSignalON) + DropField(); + + return res; + } + } + while (chaining) { // I-block with chaining - res = CmdExchangeAPDU(NULL, 0, false, &dataout[*dataoutlen], maxdataoutlen, dataoutlen, &chaining); + res = CmdExchangeAPDU(false, NULL, 0, false, &dataout[*dataoutlen], maxdataoutlen, dataoutlen, &chaining); if (res) { if (!leaveSignalON) @@ -1205,16 +1323,48 @@ int CmdHF14AAntiFuzz(const char *cmd) { return 0; } +int CmdHF14AChaining(const char *cmd) { + + CLIParserInit("hf 14a chaining", + "Enable/Disable ISO14443a input chaining. Maximum input length goes from ATS.", + "Usage:\n" + "\thf 14a chaining disable -> disable chaining\n" + "\thf 14a chaining -> show chaining enable/disable state\n"); + + void* argtable[] = { + arg_param_begin, + arg_str0(NULL, NULL, "", NULL), + arg_param_end + }; + CLIExecWithReturn(cmd, argtable, true); + + struct arg_str *str = arg_get_str(1); + int len = arg_get_str_len(1); + + if (len && (!strcmp(str->sval[0], "enable") || !strcmp(str->sval[0], "1"))) + APDUInFramingEnable = true; + + if (len && (!strcmp(str->sval[0], "disable") || !strcmp(str->sval[0], "0"))) + APDUInFramingEnable = false; + + CLIParserFree(); + + PrintAndLogEx(INFO, "\nISO 14443-4 input chaining %s.\n", APDUInFramingEnable ? "enabled" : "disabled"); + + return 0; +} + static command_t CommandTable[] = { {"help", CmdHelp, 1, "This help"}, {"list", CmdHF14AList, 0, "[Deprecated] List ISO 14443-a history"}, {"info", CmdHF14AInfo, 0, "Tag information"}, - {"reader", CmdHF14AReader, 0, "Act like an ISO14443-a reader"}, + {"reader", CmdHF14AReader, 0, "Act like an ISO14443-a reader"}, {"cuids", CmdHF14ACUIDs, 0, " Collect n>0 ISO14443-a UIDs in one go"}, - {"sim", CmdHF14ASim, 0, " -- Simulate ISO 14443-a tag"}, + {"sim", CmdHF14ASim, 0, " -- Simulate ISO 14443-a tag"}, {"sniff", CmdHF14ASniff, 0, "sniff ISO 14443-a traffic"}, {"apdu", CmdHF14AAPDU, 0, "Send ISO 14443-4 APDU to tag"}, - {"raw", CmdHF14ACmdRaw, 0, "Send raw hex data to tag"}, + {"chaining", CmdHF14AChaining, 0, "Control ISO 14443-4 input chaining"}, + {"raw", CmdHF14ACmdRaw, 0, "Send raw hex data to tag"}, {"antifuzz", CmdHF14AAntiFuzz, 0, "Fuzzing the anticollision phase. Warning! Readers may react strange"}, {NULL, NULL, 0, NULL} }; diff --git a/client/cmdhf15.c b/client/cmdhf15.c index d8a212130..2800b0c9c 100644 --- a/client/cmdhf15.c +++ b/client/cmdhf15.c @@ -519,21 +519,21 @@ int CmdHF15Info(const char *Cmd) { SendCommand(&c); if ( !WaitForResponseTimeout(CMD_ACK, &resp, 2000) ) { - PrintAndLogEx(NORMAL, "iso15693 card select failed"); + PrintAndLogEx(WARNING, "iso15693 card select failed"); return 1; } uint32_t status = resp.arg[0]; if ( status < 2 ) { - PrintAndLogEx(NORMAL, "iso15693 card doesn't answer to systeminfo command"); + PrintAndLogEx(WARNING, "iso15693 card doesn't answer to systeminfo command"); return 1; } recv = resp.d.asBytes; if ( recv[0] & ISO15_RES_ERROR ) { - PrintAndLogEx(NORMAL, "iso15693 card returned error %i: %s", recv[0], TagErrorStr(recv[0])); + PrintAndLogEx(WARNING, "iso15693 card returned error %i: %s", recv[0], TagErrorStr(recv[0])); return 3; } @@ -575,8 +575,8 @@ int CmdHF15Info(const char *Cmd) { // Record Activity without enabeling carrier //helptext int CmdHF15Record(const char *Cmd) { - char cmdp = param_getchar(Cmd, 0); - if (cmdp == 'h' || cmdp == 'H') return usage_15_record(); + char cmdp = tolower(param_getchar(Cmd, 0)); + if (cmdp == 'h') return usage_15_record(); UsbCommand c = {CMD_RECORD_RAW_ADC_SAMPLES_ISO_15693, {0,0,0}}; clearCommandBuffer(); @@ -598,8 +598,8 @@ int HF15Reader(const char *Cmd, bool verbose) { } int CmdHF15Reader(const char *Cmd) { - char cmdp = param_getchar(Cmd, 0); - if (cmdp == 'h' || cmdp == 'H') return usage_15_reader(); + char cmdp = tolower(param_getchar(Cmd, 0)); + if (cmdp == 'h') return usage_15_reader(); HF15Reader(Cmd, true); return 0; @@ -608,16 +608,16 @@ int CmdHF15Reader(const char *Cmd) { // Simulation is still not working very good // helptext int CmdHF15Sim(const char *Cmd) { - char cmdp = param_getchar(Cmd, 0); - if (strlen(Cmd) < 1 || cmdp == 'h' || cmdp == 'H') return usage_15_sim(); + char cmdp =tolower(param_getchar(Cmd, 0)); + if (strlen(Cmd) < 1 || cmdp == 'h') return usage_15_sim(); uint8_t uid[8] = {0,0,0,0,0,0,0,0}; if (param_gethex(Cmd, 0, uid, 16)) { - PrintAndLogEx(NORMAL, "UID must include 16 HEX symbols"); + PrintAndLogEx(WARNING, "UID must include 16 HEX symbols"); return 0; } - PrintAndLogEx(NORMAL, "Starting simulating UID %s", sprint_hex(uid, sizeof(uid)) ); + PrintAndLogEx(SUCCESS, "Starting simulating UID %s", sprint_hex(uid, sizeof(uid)) ); UsbCommand c = {CMD_SIMTAG_ISO_15693, {0, 0, 0}}; memcpy(c.d.asBytes, uid, 8); @@ -630,10 +630,10 @@ int CmdHF15Sim(const char *Cmd) { // (There is no standard way of reading the AFI, allthough some tags support this) // helptext int CmdHF15Afi(const char *Cmd) { - char cmdp = param_getchar(Cmd, 0); - if (cmdp == 'h' || cmdp == 'H') return usage_15_findafi(); + char cmdp = tolower(param_getchar(Cmd, 0)); + if (cmdp == 'h') return usage_15_findafi(); - PrintAndLogEx(NORMAL, "press pm3-button to cancel"); + PrintAndLogEx(SUCCESS, "press pm3-button to cancel"); UsbCommand c = {CMD_ISO_15693_FIND_AFI, {strtol(Cmd, NULL, 0), 0, 0}}; clearCommandBuffer(); @@ -689,7 +689,7 @@ int CmdHF15Dump(const char*Cmd) { } // detect blocksize from card :) - PrintAndLogEx(NORMAL, "Reading memory from tag UID %s", sprintUID(NULL, uid)); + PrintAndLogEx(NORMAL, "Reading memory from tag UID " _YELLOW_(%s), sprintUID(NULL, uid)); int blocknum = 0; uint8_t *recv = NULL; @@ -764,7 +764,7 @@ int CmdHF15Dump(const char*Cmd) { } int CmdHF15Restore(const char*Cmd) { - FILE *file; + FILE *f; uint8_t uid[8]={0x00}; char filename[FILE_PATH_SIZE] = {0x00}; @@ -774,10 +774,10 @@ int CmdHF15Restore(const char*Cmd) { char newCmdPrefix[255] = {0x00}, tmpCmd[255] = {0x00}; char param[FILE_PATH_SIZE]=""; char hex[255]=""; - uint8_t retries = 3, tried = 0; + uint8_t retries = 3, tried = 0, i = 0; int retval=0; size_t bytes_read; - uint8_t i=0; + while(param_getchar(Cmd, cmdp) != 0x00) { switch(tolower(param_getchar(Cmd, cmdp))) { case '-': @@ -785,7 +785,8 @@ int CmdHF15Restore(const char*Cmd) { switch(param[1]) { case '2': - case 'o': strncpy(newCmdPrefix, " ",sizeof(newCmdPrefix)-1); + case 'o': + strncpy(newCmdPrefix, " ", sizeof(newCmdPrefix)-1); strncat(newCmdPrefix, param, sizeof(newCmdPrefix)-1); break; default: @@ -815,18 +816,18 @@ int CmdHF15Restore(const char*Cmd) { default: PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); return usage_15_restore(); - break; } cmdp++; } + PrintAndLogEx(INFO,"Blocksize: %u",blocksize); - if(filename[0]=='\0') - { + + if ( !strlen(filename)) { PrintAndLogEx(WARNING,"Please provide a filename"); - return 1; + return usage_15_restore(); } - if ((file = fopen(filename,"rb")) == NULL) { + if ((f = fopen(filename, "rb")) == NULL) { PrintAndLogEx(WARNING, "Could not find file %s", filename); return 2; } @@ -835,40 +836,43 @@ int CmdHF15Restore(const char*Cmd) { PrintAndLogEx(WARNING, "No tag found"); return 3; } + while (1) { - tried=0; - hex[0]=0x00; - tmpCmd[0]=0x00; + tried = 0; + hex[0] = 0x00; + tmpCmd[0] = 0x00; - bytes_read = fread( buff, 1, blocksize, file ); + bytes_read = fread( buff, 1, blocksize, f ); if ( bytes_read == 0) { - PrintAndLogEx(SUCCESS, "File reading done (%s).", filename); - fclose(file); + PrintAndLogEx(SUCCESS, "File reading done `%s`", filename); + fclose(f); return 0; - } - else if ( bytes_read != blocksize) { + } else if ( bytes_read != blocksize) { PrintAndLogEx(WARNING, "File reading error (%s), %u bytes read instead of %u bytes.", filename, bytes_read, blocksize); - fclose(file); + fclose(f); return 2; } - for(int j=0;j= retries) return retval; + i++; } - fclose(file); + fclose(f); } int CmdHF15List(const char *Cmd) { @@ -1241,7 +1245,7 @@ int CmdHF15Write(const char *Cmd) { AddCrc(req, reqlen); c.arg[0] = reqlen+2; - PrintAndLogEx(NORMAL, "iso15693 writing to page %02d (0x&02X) | data ", pagenum, pagenum); + PrintAndLogEx(NORMAL, "iso15693 writing to page %02d (0x%02X) | data ", pagenum, pagenum); clearCommandBuffer(); SendCommand(&c); diff --git a/client/cmdhfepa.c b/client/cmdhfepa.c index b681810ed..dd110c9c0 100644 --- a/client/cmdhfepa.c +++ b/client/cmdhfepa.c @@ -43,7 +43,7 @@ int CmdHFEPACollectPACENonces(const char *Cmd) PrintAndLogEx(FAILED, "Error in step %d, Return code: %d",resp.arg[0],(int)resp.arg[1]); } else { size_t nonce_length = resp.arg[1]; - char *nonce = (char *) malloc(2 * nonce_length + 1); + char *nonce = (char *) calloc(2 * nonce_length + 1, sizeof(uint8_t)); for(int j = 0; j < nonce_length; j++) { sprintf(nonce + (2 * j), "%02X", resp.d.asBytes[j]); } diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 0e62afaf6..9427acf50 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -404,7 +404,7 @@ int CmdHFiClassSim(const char *Cmd) { break; size_t datalen = NUM_CSNS * 24; - void* dump = malloc(datalen); + void* dump = calloc(datalen, sizeof(uint8_t)); if ( !dump ) { PrintAndLogEx(WARNING, "Failed to allocate memory"); return 2; @@ -456,7 +456,7 @@ int CmdHFiClassSim(const char *Cmd) { break; size_t datalen = NUM_CSNS * 24; - void* dump = malloc(datalen); + void* dump = calloc(datalen, sizeof(uint8_t)); if ( !dump ) { PrintAndLogEx(WARNING, "Failed to allocate memory"); return 2; @@ -2463,7 +2463,7 @@ static void shave(uint8_t *data, uint8_t len){ data[i] &= 0xFE; } static void generate_rev(uint8_t *data, uint8_t len) { - uint8_t *key = calloc(len,1); + uint8_t *key = calloc(len, sizeof(uint8_t)); PrintAndLogEx(SUCCESS, "input permuted key | %s \n", sprint_hex(data, len)); permute_rev(data, len, key); PrintAndLogEx(SUCCESS, " unpermuted key | %s \n", sprint_hex(key, len)); @@ -2472,8 +2472,8 @@ static void generate_rev(uint8_t *data, uint8_t len) { free(key); } static void generate(uint8_t *data, uint8_t len) { - uint8_t *key = calloc(len,1); - uint8_t *pkey = calloc(len,1); + uint8_t *key = calloc(len, sizeof(uint8_t)); + uint8_t *pkey = calloc(len, sizeof(uint8_t)); PrintAndLogEx(SUCCESS, " input key | %s \n", sprint_hex(data, len)); permute(data, len, pkey); PrintAndLogEx(SUCCESS, "permuted key | %s \n", sprint_hex(pkey, len)); diff --git a/client/cmdhflegic.c b/client/cmdhflegic.c index 393d73ed0..8c4ef411c 100644 --- a/client/cmdhflegic.c +++ b/client/cmdhflegic.c @@ -180,15 +180,14 @@ int CmdLegicInfo(const char *Cmd) { return 1; } - PrintAndLogEx(NORMAL, "Reading tag memory %d b...", card.cardsize); + PrintAndLogEx(SUCCESS, "Reading tag memory %d b...", card.cardsize); // allocate receiver buffer - uint8_t *data = malloc(card.cardsize); + uint8_t *data = calloc(card.cardsize, sizeof(uint8_t)); if (!data) { PrintAndLogEx(WARNING, "Cannot allocate memory"); return 2; } - memset(data, 0, card.cardsize); int status = legic_read_mem(0, card.cardsize, 0x55, data, &datalen); if ( status > 0 ) { @@ -480,15 +479,20 @@ int CmdLegicRdmem(const char *Cmd) { uint16_t datalen = 0; sscanf(Cmd, "%x %x %x", &offset, &len, &iv); - PrintAndLogEx(NORMAL, "Reading %d bytes, from offset %d", len, offset); + // sanity checks + if ( len + offset >= MAX_LENGTH ) { + PrintAndLogEx(WARNING, "Out-of-bounds, Cardsize = %d, [offset+len = %d ]", MAX_LENGTH, len + offset); + return -1; + } + + PrintAndLogEx(SUCCESS, "Reading %d bytes, from offset %d", len, offset); // allocate receiver buffer - uint8_t *data = malloc(len); + uint8_t *data = calloc(len, sizeof(uint8_t)); if ( !data ){ PrintAndLogEx(WARNING, "Cannot allocate memory"); - return 2; + return -2; } - memset(data, 0, len); int status = legic_read_mem(offset, len, iv, data, &datalen); if ( status == 0 ) { @@ -540,9 +544,9 @@ int CmdLegicRfWrite(const char *Cmd) { } // limit number of bytes to write. This is not a 'restore' command. - if ( (len>>1) > 100 ){ - PrintAndLogEx(NORMAL, "Max bound on 100bytes to write a one time."); - PrintAndLogEx(NORMAL, "Use the 'hf legic restore' command if you want to write the whole tag at once"); + if ( (len >> 1) > 100 ){ + PrintAndLogEx(WARNING, "Max bound on 100bytes to write a one time."); + PrintAndLogEx(WARNING, "Use the 'hf legic restore' command if you want to write the whole tag at once"); errors = true; } @@ -551,7 +555,7 @@ int CmdLegicRfWrite(const char *Cmd) { if (data) free(data); - data = malloc(len >> 1); + data = calloc(len >> 1, sizeof(uint8_t)); if ( data == NULL ) { PrintAndLogEx(WARNING, "Can't allocate memory. exiting"); errors = true; @@ -598,12 +602,12 @@ int CmdLegicRfWrite(const char *Cmd) { // OUT-OF-BOUNDS checks // UID 4+1 bytes can't be written to. if ( offset < 5 ) { - PrintAndLogEx(NORMAL, "Out-of-bounds, bytes 0-1-2-3-4 can't be written to. Offset = %d", offset); + PrintAndLogEx(WARNING, "Out-of-bounds, bytes 0-1-2-3-4 can't be written to. Offset = %d", offset); return -2; } if ( len + offset >= card.cardsize ) { - PrintAndLogEx(NORMAL, "Out-of-bounds, Cardsize = %d, [offset+len = %d ]", card.cardsize, len + offset); + PrintAndLogEx(WARNING, "Out-of-bounds, Cardsize = %d, [offset+len = %d ]", card.cardsize, len + offset); return -2; } @@ -622,7 +626,7 @@ int CmdLegicRfWrite(const char *Cmd) { legic_chk_iv(&IV); - PrintAndLogEx(NORMAL, "Writing to tag"); + PrintAndLogEx(SUCCESS, "Writing to tag"); UsbCommand c = {CMD_WRITER_LEGIC_RF, {offset, len, IV}}; memcpy(c.d.asBytes, data, len); @@ -630,10 +634,18 @@ int CmdLegicRfWrite(const char *Cmd) { clearCommandBuffer(); SendCommand(&c); - if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { - PrintAndLogEx(WARNING, "command execution time out"); - return 1; - } + + uint8_t timeout = 0; + while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { + ++timeout; + printf("."); fflush(stdout); + if (timeout > 7) { + PrintAndLogEx(WARNING, "\ncommand execution time out"); + return 1; + } + } + PrintAndLogEx(NORMAL, "\n"); + uint8_t isOK = resp.arg[0] & 0xFF; if ( !isOK ) { PrintAndLogEx(WARNING, "Failed writing tag"); @@ -673,7 +685,7 @@ int CmdLegicCalcCrc(const char *Cmd){ // it's possible for user to accidentally enter "b" parameter // more than once - we have to clean previous malloc if (data) free(data); - data = malloc(len >> 1); + data = calloc(len >> 1, sizeof(uint8_t) ); if ( data == NULL ) { PrintAndLogEx(WARNING, "Can't allocate memory. exiting"); errors = true; @@ -714,10 +726,10 @@ int CmdLegicCalcCrc(const char *Cmd){ switch (type){ case 16: init_table(CRC_LEGIC); - PrintAndLogEx(NORMAL, "Legic crc16: %X", crc16_legic(data, len, uidcrc)); + PrintAndLogEx(SUCCESS, "Legic crc16: %X", crc16_legic(data, len, uidcrc)); break; default: - PrintAndLogEx(NORMAL, "Legic crc8: %X", CRC8Legic(data, len) ); + PrintAndLogEx(SUCCESS, "Legic crc8: %X", CRC8Legic(data, len) ); break; } @@ -733,11 +745,18 @@ int legic_read_mem(uint32_t offset, uint32_t len, uint32_t iv, uint8_t *out, uin clearCommandBuffer(); SendCommand(&c); UsbCommand resp; - if ( !WaitForResponseTimeout(CMD_ACK, &resp, 3000) ) { - PrintAndLogEx(WARNING, "command execution time out"); - return 1; - } - + + uint8_t timeout = 0; + while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { + ++timeout; + printf("."); fflush(stdout); + if (timeout > 7) { + PrintAndLogEx(WARNING, "\ncommand execution time out"); + return 1; + } + } + PrintAndLogEx(NORMAL, "\n"); + uint8_t isOK = resp.arg[0] & 0xFF; *outlen = resp.arg[1]; if ( !isOK ) { @@ -762,13 +781,13 @@ int legic_print_type(uint32_t tagtype, uint8_t spaces){ char *spacer = spc + (10-spaces); if ( tagtype == 22 ) - PrintAndLogEx(NORMAL, "%sTYPE : MIM%d card (outdated)", spacer, tagtype); + PrintAndLogEx(SUCCESS, "%sTYPE : MIM%d card (outdated)", spacer, tagtype); else if ( tagtype == 256 ) - PrintAndLogEx(NORMAL, "%sTYPE : MIM%d card (234 bytes)", spacer, tagtype); + PrintAndLogEx(SUCCESS, "%sTYPE : MIM%d card (234 bytes)", spacer, tagtype); else if ( tagtype == 1024 ) - PrintAndLogEx(NORMAL, "%sTYPE : MIM%d card (1002 bytes)", spacer, tagtype); + PrintAndLogEx(SUCCESS, "%sTYPE : MIM%d card (1002 bytes)", spacer, tagtype); else - PrintAndLogEx(NORMAL, "%sTYPE : Unknown %06x", spacer, tagtype); + PrintAndLogEx(INFO, "%sTYPE : Unknown %06x", spacer, tagtype); return 0; } int legic_get_type(legic_card_select_t *card){ @@ -792,12 +811,12 @@ int legic_get_type(legic_card_select_t *card){ void legic_chk_iv(uint32_t *iv){ if ( (*iv & 0x7F) != *iv ){ *iv &= 0x7F; - PrintAndLogEx(NORMAL, "Truncating IV to 7bits, %u", *iv); + PrintAndLogEx(INFO, "Truncating IV to 7bits, %u", *iv); } // IV must be odd if ( (*iv & 1) == 0 ){ *iv |= 0x01; - PrintAndLogEx(NORMAL, "LSB of IV must be SET %u", *iv); + PrintAndLogEx(INFO, "LSB of IV must be SET %u", *iv); } } void legic_seteml(uint8_t *src, uint32_t offset, uint32_t numofbytes) { @@ -828,11 +847,11 @@ int HFLegicReader(const char *Cmd, bool verbose) { if ( verbose ) PrintAndLogEx(WARNING, "command execution time out"); return 1; case 3: - if ( verbose ) PrintAndLogEx(NORMAL, "legic card select failed"); + if ( verbose ) PrintAndLogEx(WARNING, "legic card select failed"); return 2; default: break; } - PrintAndLogEx(NORMAL, " UID : %s", sprint_hex(card.uid, sizeof(card.uid))); + PrintAndLogEx(SUCCESS, " UID : %s", sprint_hex(card.uid, sizeof(card.uid))); legic_print_type(card.cardsize, 0); return 0; } @@ -882,16 +901,23 @@ int CmdLegicDump(const char *Cmd){ dumplen = card.cardsize; legic_print_type(dumplen, 0); - PrintAndLogEx(NORMAL, "Reading tag memory %d b...", dumplen); + PrintAndLogEx(SUCCESS, "Reading tag memory %d b...", dumplen); UsbCommand c = {CMD_READER_LEGIC_RF, {0x00, dumplen, 0x55}}; clearCommandBuffer(); SendCommand(&c); UsbCommand resp; - if (!WaitForResponseTimeout(CMD_ACK, &resp, 3000)) { - PrintAndLogEx(NORMAL, "Command execute time-out"); - return 1; - } + + uint8_t timeout = 0; + while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { + ++timeout; + printf("."); fflush(stdout); + if (timeout > 7) { + PrintAndLogEx(WARNING, "\ncommand execution time out"); + return 1; + } + } + PrintAndLogEx(NORMAL, "\n"); uint8_t isOK = resp.arg[0] & 0xFF; if ( !isOK ) { @@ -900,12 +926,11 @@ int CmdLegicDump(const char *Cmd){ } uint16_t readlen = resp.arg[1]; - uint8_t *data = malloc(readlen); + uint8_t *data = calloc(readlen, sizeof(uint8_t)); if (!data) { PrintAndLogEx(WARNING, "Fail, cannot allocate memory"); return 3; } - memset(data, 0, readlen); if ( readlen != dumplen ) PrintAndLogEx(WARNING, "Fail, only managed to read 0x%02X bytes of 0x%02X", readlen, dumplen); @@ -923,7 +948,7 @@ int CmdLegicDump(const char *Cmd){ else sprintf(fnameptr + fileNlen,".bin"); - f = fopen(filename,"wb"); + f = fopen(filename, "wb"); if (!f) { PrintAndLogEx(WARNING, "Could not create file name %s", filename); if (data) @@ -934,7 +959,7 @@ int CmdLegicDump(const char *Cmd){ fflush(f); fclose(f); free(data); - PrintAndLogEx(NORMAL, "Wrote %d bytes to %s", readlen, filename); + PrintAndLogEx(SUCCESS, "Wrote %d bytes to %s", readlen, filename); return 0; } @@ -982,12 +1007,11 @@ int CmdLegicRestore(const char *Cmd){ numofbytes = card.cardsize; // set up buffer - uint8_t *data = malloc(numofbytes); + uint8_t *data = calloc(numofbytes, sizeof(uint8_t) ); if (!data) { PrintAndLogEx(WARNING, "Fail, cannot allocate memory"); return 2; } - memset(data, 0, numofbytes); legic_print_type(numofbytes, 0); @@ -997,7 +1021,7 @@ int CmdLegicRestore(const char *Cmd){ f = fopen(filename,"rb"); if (!f) { - PrintAndLogEx(NORMAL, "File %s not found or locked", filename); + PrintAndLogEx(WARNING, "File %s not found or locked", filename); return 3; } @@ -1018,12 +1042,12 @@ int CmdLegicRestore(const char *Cmd){ fclose(f); if ( bytes_read == 0){ - PrintAndLogEx(NORMAL, "File reading error"); + PrintAndLogEx(WARNING, "File reading error"); free(data); return 2; } - PrintAndLogEx(NORMAL, "Restoring to card"); + PrintAndLogEx(SUCCESS, "Restoring to card"); // transfer to device size_t len = 0; @@ -1038,22 +1062,29 @@ int CmdLegicRestore(const char *Cmd){ clearCommandBuffer(); SendCommand(&c); - if (!WaitForResponseTimeout(CMD_ACK, &resp, 4000)) { - PrintAndLogEx(WARNING, "command execution time out"); - free(data); - return 1; - } + uint8_t timeout = 0; + while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { + ++timeout; + printf("."); fflush(stdout); + if (timeout > 7) { + PrintAndLogEx(WARNING, "\ncommand execution time out"); + free(data); + return 1; + } + } + PrintAndLogEx(NORMAL, "\n"); + uint8_t isOK = resp.arg[0] & 0xFF; if ( !isOK ) { PrintAndLogEx(WARNING, "Failed writing tag [msg = %u]", resp.arg[1] & 0xFF); free(data); return 1; } - PrintAndLogEx(NORMAL, "Wrote chunk [offset %d | len %d | total %d", i, len, i+len); + PrintAndLogEx(SUCCESS, "Wrote chunk [offset %d | len %d | total %d", i, len, i+len); } free(data); - PrintAndLogEx(NORMAL, "\nWrote %d bytes to card from file %s", numofbytes, filename); + PrintAndLogEx(SUCCESS, "\nWrote %d bytes to card from file %s", numofbytes, filename); return 0; } @@ -1077,12 +1108,11 @@ int CmdLegicELoad(const char *Cmd) { } // set up buffer - uint8_t *data = malloc(numofbytes); + uint8_t *data = calloc(numofbytes, sizeof(uint8_t)); if (!data) { PrintAndLogEx(WARNING, "Fail, cannot allocate memory"); return 3; } - memset(data, 0, numofbytes); // set up file len = param_getstr(Cmd, nameParamNo, filename, FILE_PATH_SIZE); @@ -1094,7 +1124,7 @@ int CmdLegicELoad(const char *Cmd) { // open file f = fopen(filename,"rb"); if (!f) { - PrintAndLogEx(NORMAL, "File %s not found or locked", filename); + PrintAndLogEx(WARNING, "File %s not found or locked", filename); free(data); return 1; } @@ -1102,7 +1132,7 @@ int CmdLegicELoad(const char *Cmd) { // load file size_t bytes_read = fread(data, 1, numofbytes, f); if ( bytes_read == 0){ - PrintAndLogEx(NORMAL, "File reading error"); + PrintAndLogEx(WARNING, "File reading error"); free(data); fclose(f); f = NULL; @@ -1115,7 +1145,7 @@ int CmdLegicELoad(const char *Cmd) { legic_seteml(data, 0, numofbytes); free(data); - PrintAndLogEx(NORMAL, "\nLoaded %d bytes from file: %s to emulator memory", numofbytes, filename); + PrintAndLogEx(SUCCESS, "\nLoaded %d bytes from file: %s to emulator memory", numofbytes, filename); return 0; } @@ -1146,15 +1176,14 @@ int CmdLegicESave(const char *Cmd) { fileNlen = FILE_PATH_SIZE - 5; // set up buffer - uint8_t *data = malloc(numofbytes); + uint8_t *data = calloc(numofbytes, sizeof(uint8_t)); if (!data) { PrintAndLogEx(WARNING, "Fail, cannot allocate memory"); return 3; } - memset(data, 0, numofbytes); // download emulator memory - PrintAndLogEx(NORMAL, "Reading emulator memory..."); + PrintAndLogEx(SUCCESS, "Reading emulator memory..."); if (!GetFromDevice( BIG_BUF_EML, data, numofbytes, 0, NULL, 2500, false)) { PrintAndLogEx(WARNING, "Fail, transfer from device time-out"); free(data); @@ -1185,16 +1214,15 @@ int CmdLegicWipe(const char *Cmd){ } // set up buffer - uint8_t *data = malloc(card.cardsize); + uint8_t *data = calloc(card.cardsize, sizeof(uint8_t)); if (!data) { PrintAndLogEx(WARNING, "Fail, cannot allocate memory"); return 2; } - memset(data, 0, card.cardsize); legic_print_type(card.cardsize, 0); - PrintAndLogEx(NORMAL, "Erasing"); + PrintAndLogEx(SUCCESS, "Erasing"); // transfer to device size_t len = 0; @@ -1210,11 +1238,18 @@ int CmdLegicWipe(const char *Cmd){ clearCommandBuffer(); SendCommand(&c); - if (!WaitForResponseTimeout(CMD_ACK, &resp, 4000)) { - PrintAndLogEx(WARNING, "command execution time out"); - free(data); - return 3; - } + uint8_t timeout = 0; + while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { + ++timeout; + printf("."); fflush(stdout); + if (timeout > 7) { + PrintAndLogEx(WARNING, "\ncommand execution time out"); + free(data); + return 3; + } + } + PrintAndLogEx(NORMAL, "\n"); + uint8_t isOK = resp.arg[0] & 0xFF; if ( !isOK ) { PrintAndLogEx(WARNING, "Failed writing tag [msg = %u]", resp.arg[1] & 0xFF); @@ -1222,7 +1257,7 @@ int CmdLegicWipe(const char *Cmd){ return 4; } } - PrintAndLogEx(NORMAL, "ok\n"); + PrintAndLogEx(SUCCESS, "ok\n"); return 0; } @@ -1236,7 +1271,7 @@ static command_t CommandTable[] = { {"reader", CmdLegicReader, 1, "LEGIC Prime Reader UID and tag info"}, {"info", CmdLegicInfo, 0, "Display deobfuscated and decoded LEGIC Prime tag data"}, {"dump", CmdLegicDump, 0, "Dump LEGIC Prime tag to binary file"}, - {"restore", CmdLegicRestore, 0, "Restore a dump onto a LEGIC Prime tag"}, + {"restore", CmdLegicRestore, 0, "Restore a dump file onto a LEGIC Prime tag"}, {"rdmem", CmdLegicRdmem, 0, "Read bytes from a LEGIC Prime tag"}, {"sim", CmdLegicRfSim, 0, "Start tag simulator"}, {"write", CmdLegicRfWrite, 0, "Write data to a LEGIC Prime tag"}, diff --git a/client/cmdhflist.c b/client/cmdhflist.c index 7791c5e53..b2e0eeecc 100644 --- a/client/cmdhflist.c +++ b/client/cmdhflist.c @@ -357,7 +357,7 @@ void annotateIso7816(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize){ case ISO7816_EXTERNAL_AUTHENTICATION :snprintf(exp, size, "EXTERNAL AUTH");break; case ISO7816_GET_CHALLENGE :snprintf(exp, size, "GET CHALLENGE");break; case ISO7816_MANAGE_CHANNEL :snprintf(exp, size, "MANAGE CHANNEL");break; - case ISO7816_GETSTATUS :snprintf(exp, size, "GET RESPONSE");break; + case ISO7816_GET_RESPONSE :snprintf(exp, size, "GET RESPONSE");break; default :snprintf(exp,size,"?"); break; } } diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 00e29105f..47646852e 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -11,11 +11,16 @@ #include "cmdhfmf.h" #include "mifare4.h" -#define MIFARE_4K_MAXBLOCK 255 +#define MIFARE_4K_MAXBLOCK 256 #define MIFARE_2K_MAXBLOCK 128 #define MIFARE_1K_MAXBLOCK 64 #define MIFARE_MINI_MAXBLOCK 20 +#define MIFARE_MINI_MAXSECTOR 5 +#define MIFARE_1K_MAXSECTOR 16 +#define MIFARE_2K_MAXSECTOR 32 +#define MIFARE_4K_MAXSECTOR 40 + static int CmdHelp(const char *Cmd); int usage_hf14_ice(void){ @@ -415,7 +420,7 @@ int GetHFMF14AUID(uint8_t *uid, int *uidlen) { char * GenerateFilename(const char *prefix, const char *suffix){ uint8_t uid[10] = {0,0,0,0,0,0,0,0,0,0}; int uidlen=0; - char * fptr = malloc (sizeof (char) * (strlen(prefix) + strlen(suffix)) + sizeof(uid)*2 + 1); + char * fptr = calloc (sizeof (char) * (strlen(prefix) + strlen(suffix)) + sizeof(uid)*2 + 1, sizeof(uint8_t)); GetHFMF14AUID(uid, &uidlen); if (!uidlen) { @@ -591,7 +596,7 @@ int CmdHF14AMfRdSc(const char *Cmd) { } sectorNo = param_get8(Cmd, 0); - if (sectorNo > 39) { + if (sectorNo > MIFARE_4K_MAXSECTOR ) { PrintAndLogEx(NORMAL, "Sector number must be less than 40"); return 1; } @@ -645,7 +650,7 @@ int CmdHF14AMfRdSc(const char *Cmd) { return 0; } -uint8_t NumOfBlocks(char card){ +uint16_t NumOfBlocks(char card){ switch(card){ case '0' : return MIFARE_MINI_MAXBLOCK; case '1' : return MIFARE_1K_MAXBLOCK; @@ -656,11 +661,11 @@ uint8_t NumOfBlocks(char card){ } uint8_t NumOfSectors(char card){ switch(card){ - case '0' : return 5; - case '1' : return 16; - case '2' : return 32; - case '4' : return 40; - default : return 16; + case '0' : return MIFARE_MINI_MAXSECTOR; + case '1' : return MIFARE_1K_MAXSECTOR; + case '2' : return MIFARE_2K_MAXSECTOR; + case '4' : return MIFARE_4K_MAXSECTOR; + default : return MIFARE_1K_MAXSECTOR; } } @@ -729,7 +734,7 @@ int CmdHF14AMfDump(const char *Cmd) { } if ((fin = fopen(keyFilename, "rb")) == NULL) { - PrintAndLogEx(WARNING, "Could not find file %s", keyFilename); + PrintAndLogEx(WARNING, "Could not find file " _YELLOW_(%s), keyFilename); return 1; } @@ -738,7 +743,7 @@ int CmdHF14AMfDump(const char *Cmd) { for (sectorNo=0; sectorNo 0xffffffffffff has been inserted for unknown keys.", fptr); + FILE *fkeys = fopen(fptr, "wb"); + if (fkeys == NULL) { + PrintAndLogEx(WARNING, "Could not create file " _YELLOW_(%s), fptr); + free(keyBlock); + free(e_sector); + return 1; + } + PrintAndLogEx(SUCCESS, "Printing keys to binary file " _YELLOW_(%s)"...", fptr); + + for (i=0; i 0xffffffffffff has been inserted for unknown keys.", fptr); + } } free(keyBlock); @@ -1695,8 +1716,8 @@ out: int CmdHF14AMfChk(const char *Cmd) { - char ctmp = param_getchar(Cmd, 0); - if (strlen(Cmd) < 3 || ctmp == 'h' || ctmp == 'H') return usage_hf14_chk(); + char ctmp = tolower(param_getchar(Cmd, 0)); + if (strlen(Cmd) < 3 || ctmp == 'h') return usage_hf14_chk(); FILE * f; char filename[FILE_PATH_SIZE]={0}; @@ -1729,23 +1750,21 @@ int CmdHF14AMfChk(const char *Cmd) { blockNo = param_get8(Cmd, 0); } - ctmp = param_getchar(Cmd, 1); + ctmp = tolower(param_getchar(Cmd, 1)); clen = param_getlength(Cmd, 1); if (clen == 1) { switch (ctmp) { case 'a': - case 'A': keyType = 0; break; case 'b': - case 'B': keyType = 1; break; case '?': keyType = 2; break; default: - PrintAndLogEx(NORMAL, "Key type must be A , B or ?"); + PrintAndLogEx(FAILED, "Key type must be A , B or ?"); free(keyBlock); return 1; }; @@ -1753,7 +1772,7 @@ int CmdHF14AMfChk(const char *Cmd) { for (i = 2; param_getchar(Cmd, i); i++) { - ctmp = param_getchar(Cmd, i); + ctmp = tolower(param_getchar(Cmd, i)); clen = param_getlength(Cmd, i); if (clen == 12) { @@ -1775,8 +1794,8 @@ int CmdHF14AMfChk(const char *Cmd) { PrintAndLogEx(NORMAL, "[%2d] key %s", keycnt, sprint_hex( (keyBlock + 6*keycnt), 6 ) );; keycnt++; } else if ( clen == 1 ) { - if (ctmp == 't' || ctmp == 'T') { transferToEml = 1; continue; } - if (ctmp == 'd' || ctmp == 'D') { createDumpFile = 1; continue; } + if (ctmp == 't' ) { transferToEml = 1; continue; } + if (ctmp == 'd' ) { createDumpFile = 1; continue; } } else { // May be a dic file if ( param_getstr(Cmd, i, filename, sizeof(filename)) >= FILE_PATH_SIZE ) { @@ -1786,7 +1805,7 @@ int CmdHF14AMfChk(const char *Cmd) { f = fopen( filename , "r"); if ( !f ) { - PrintAndLogEx(FAILED, "File: %s: not found or locked.", filename); + PrintAndLogEx(FAILED, "File: " _YELLOW_(%s)": not found or locked.", filename); continue; } @@ -1801,7 +1820,7 @@ int CmdHF14AMfChk(const char *Cmd) { // codesmell, only checks first char? if (!isxdigit(buf[0])){ - PrintAndLogEx(FAILED, "File content error. '%s' must include 12 HEX symbols",buf); + PrintAndLogEx(FAILED, "File content error. '" _YELLOW_(%s)"' must include 12 HEX symbols",buf); continue; } @@ -1824,12 +1843,12 @@ int CmdHF14AMfChk(const char *Cmd) { memset(buf, 0, sizeof(buf)); } fclose(f); - PrintAndLogEx(SUCCESS, "Loaded %2d keys from %s", keycnt, filename); + PrintAndLogEx(SUCCESS, "Loaded %2d keys from " _YELLOW_(%s), keycnt, filename); } } if (keycnt == 0) { - PrintAndLogEx(NORMAL, "No key specified, trying default keys"); + PrintAndLogEx(INFO, "No key specified, trying default keys"); for (;keycnt < MIFARE_DEFAULTKEYS_SIZE; keycnt++) PrintAndLogEx(NORMAL, "[%2d] %02x%02x%02x%02x%02x%02x", keycnt, (keyBlock + 6*keycnt)[0],(keyBlock + 6*keycnt)[1], (keyBlock + 6*keycnt)[2], @@ -1873,7 +1892,7 @@ int CmdHF14AMfChk(const char *Cmd) { printf("."); fflush(stdout); if (ukbhit()) { int gc = getchar(); (void)gc; - PrintAndLogEx(NORMAL, "\naborted via keyboard!\n"); + PrintAndLogEx(INFO, "\naborted via keyboard!\n"); goto out; } @@ -1892,12 +1911,12 @@ int CmdHF14AMfChk(const char *Cmd) { } } t1 = msclock() - t1; - PrintAndLogEx(NORMAL, "\nTime in checkkeys: %.0f seconds\n", (float)t1/1000.0); + PrintAndLogEx(SUCCESS, "\nTime in checkkeys: %.0f seconds\n", (float)t1/1000.0); // 20160116 If Sector A is found, but not Sector B, try just reading it of the tag? if ( keyType != 1 ) { - PrintAndLogEx(NORMAL, "testing to read key B..."); + PrintAndLogEx(INFO, "testing to read key B..."); for (i = 0; i < SectorsCnt; i++) { // KEY A but not KEY B if ( e_sector[i].foundKey[0] && !e_sector[i].foundKey[1] ) { @@ -1943,7 +1962,7 @@ out: num_to_bytes(e_sector[i].Key[1], 6, block+10); mfEmlSetMem(block, FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1, 1); } - PrintAndLogEx(NORMAL, "Found keys have been transferred to the emulator memory"); + PrintAndLogEx(SUCCESS, "Found keys have been transferred to the emulator memory"); } if (createDumpFile) { @@ -1953,12 +1972,12 @@ out: FILE *fkeys = fopen(fptr, "wb"); if (fkeys == NULL) { - PrintAndLogEx(WARNING, "Could not create file %s", fptr); + PrintAndLogEx(WARNING, "Could not create file " _YELLOW_(%s), fptr); free(keyBlock); free(e_sector); return 1; } - PrintAndLogEx(NORMAL, "Printing keys to binary file %s...", fptr); + PrintAndLogEx(INFO, "Printing keys to binary file " _YELLOW_(%s)"...", fptr); for( i=0; i bufsize || buf == NULL) { uint8_t *p; if (buf == NULL) // not yet allocated - p = malloc(traceLen); + p = calloc(traceLen, sizeof(uint8_t)); else // need more memory p = realloc(buf, traceLen); @@ -2412,14 +2431,14 @@ int CmdHF14AMfELoad(const char *Cmd) { return usage_hf14_eload(); switch (c) { - case '0' : numBlocks = 5*4; break; + case '0' : numBlocks = MIFARE_MINI_MAXBLOCK; break; case '1' : - case '\0': numBlocks = 16*4; break; - case '2' : numBlocks = 32*4; break; - case '4' : numBlocks = 256; break; + case '\0': numBlocks = MIFARE_1K_MAXBLOCK; break; + case '2' : numBlocks = MIFARE_2K_MAXBLOCK; break; + case '4' : numBlocks = MIFARE_4K_MAXBLOCK; break; case 'u' : numBlocks = 255; blockWidth = 4; break; default: { - numBlocks = 16*4; + numBlocks = MIFARE_1K_MAXBLOCK; nameParamNo = 0; } } @@ -2475,7 +2494,7 @@ int CmdHF14AMfELoad(const char *Cmd) { return 4; } } - PrintAndLogEx(SUCCESS, "Loaded %d blocks from file: %s", blockNum, filename); + PrintAndLogEx(SUCCESS, "Loaded %d blocks from file: " _YELLOW_(%s), blockNum, filename); return 0; } @@ -2496,14 +2515,14 @@ int CmdHF14AMfESave(const char *Cmd) { blocks = NumOfBlocks(c); bytes = blocks * MFBLOCK_SIZE; - dump = calloc(sizeof(uint8_t), bytes); + dump = calloc(bytes, sizeof(uint8_t)); if (!dump) { PrintAndLogEx(WARNING, "Fail, cannot allocate memory"); return 1; } memset(dump, 0, bytes); - PrintAndLogEx(INFO, "dowingloading from emulator memory"); + PrintAndLogEx(INFO, "downloading from emulator memory"); if (!GetFromDevice( BIG_BUF_EML, dump, bytes, 0, NULL, 2500, false)) { PrintAndLogEx(WARNING, "Fail, transfer from device time-out"); free(dump); @@ -2761,7 +2780,7 @@ int CmdHF14AMfCLoad(const char *Cmd) { blockNum++; // magic card type - mifare 1K - if (blockNum >= 16 * 4) break; + if (blockNum >= MIFARE_1K_MAXBLOCK ) break; } PrintAndLogEx(NORMAL, "\n"); @@ -2783,8 +2802,8 @@ int CmdHF14AMfCGetBlk(const char *Cmd) { int res; memset(data, 0x00, sizeof(data)); - char ctmp = param_getchar(Cmd, 0); - if (strlen(Cmd) < 1 || ctmp == 'h' || ctmp == 'H') return usage_hf14_cgetblk(); + char ctmp = tolower(param_getchar(Cmd, 0)); + if (strlen(Cmd) < 1 || ctmp == 'h') return usage_hf14_cgetblk(); blockNo = param_get8(Cmd, 0); @@ -2819,8 +2838,8 @@ int CmdHF14AMfCGetSc(const char *Cmd) { uint8_t sector = 0; int i, res, flags; - char ctmp = param_getchar(Cmd, 0); - if (strlen(Cmd) < 1 || ctmp == 'h' || ctmp == 'H') return usage_hf14_cgetsc(); + char ctmp = tolower(param_getchar(Cmd, 0)); + if (strlen(Cmd) < 1 || ctmp == 'h') return usage_hf14_cgetsc(); sector = param_get8(Cmd, 0); if (sector > 39) { @@ -2912,7 +2931,7 @@ int CmdHF14AMfCSave(const char *Cmd) { if (errors || cmdp == 0) return usage_hf14_csave(); - dump = malloc(bytes); + dump = calloc(bytes, sizeof(uint8_t)); if (!dump) { PrintAndLogEx(WARNING, "Fail, cannot allocate memory"); return 1; @@ -2958,8 +2977,8 @@ int CmdHF14AMfCSave(const char *Cmd) { //needs nt, ar, at, Data to decrypt int CmdHf14AMfDecryptBytes(const char *Cmd){ - char ctmp = param_getchar(Cmd, 0); - if (strlen(Cmd) < 1 || ctmp == 'h' || ctmp == 'H') return usage_hf14_decryptbytes(); + char ctmp = tolower(param_getchar(Cmd, 0)); + if (strlen(Cmd) < 1 || ctmp == 'h') return usage_hf14_decryptbytes(); uint32_t nt = param_get32ex(Cmd,0,0,16); uint32_t ar_enc = param_get32ex(Cmd,1,0,16); @@ -3010,7 +3029,7 @@ int CmdHf14AMfSetMod(const char *Cmd) { UsbCommand resp; if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { uint8_t ok = resp.arg[0] & 0xff; - PrintAndLogEx(NORMAL, "isOk:%02x", ok); + PrintAndLogEx(SUCCESS, "isOk:%02x", ok); if (!ok) PrintAndLogEx(FAILED, "Failed."); } else { @@ -3023,12 +3042,12 @@ int CmdHf14AMfSetMod(const char *Cmd) { int CmdHf14AMfNack(const char *Cmd) { bool verbose = false; - char ctmp = param_getchar(Cmd, 0); - if ( ctmp == 'h' || ctmp == 'H' ) return usage_hf14_nack(); - if ( ctmp == 'v' || ctmp == 'V' ) verbose = true; + char ctmp = tolower(param_getchar(Cmd, 0)); + if ( ctmp == 'h' ) return usage_hf14_nack(); + if ( ctmp == 'v' ) verbose = true; if ( verbose ) - PrintAndLogEx(NORMAL, "Started testing card for NACK bug. Press key to abort"); + PrintAndLogEx(INFO, "Started testing card for NACK bug. Press key to abort"); detect_classic_nackbug(verbose); return 0; @@ -3086,7 +3105,7 @@ int CmdHF14AMfice(const char *Cmd) { PrintAndLogEx(NORMAL, "Collecting %u nonces \n", limit); if ((fnonces = fopen(filename,"wb")) == NULL) { - PrintAndLogEx(WARNING, "Could not create file %s",filename); + PrintAndLogEx(WARNING, "Could not create file " _YELLOW_(%s),filename); return 3; } @@ -3097,7 +3116,7 @@ int CmdHF14AMfice(const char *Cmd) { do { if (ukbhit()) { int gc = getchar(); (void)gc; - PrintAndLogEx(NORMAL, "\naborted via keyboard!\n"); + PrintAndLogEx(INFO, "\naborted via keyboard!\n"); break; } @@ -3119,7 +3138,7 @@ int CmdHF14AMfice(const char *Cmd) { total_num_nonces += items; if ( total_num_nonces > part_limit ) { - PrintAndLogEx(NORMAL, "Total nonces %u\n", total_num_nonces); + PrintAndLogEx(INFO, "Total nonces %u\n", total_num_nonces); part_limit += 3000; } @@ -3130,7 +3149,7 @@ int CmdHF14AMfice(const char *Cmd) { } while (!acquisition_completed); out: - PrintAndLogEx(NORMAL, "time: %" PRIu64 " seconds\n", (msclock()-t1)/1000); + PrintAndLogEx(SUCCESS, "time: %" PRIu64 " seconds\n", (msclock()-t1)/1000); if ( fnonces ) { fflush(fnonces); diff --git a/client/cmdhfmfhard.c b/client/cmdhfmfhard.c index 07e05a81e..4818f480f 100644 --- a/client/cmdhfmfhard.c +++ b/client/cmdhfmfhard.c @@ -209,7 +209,7 @@ static int compare_count_bitflip_bitarrays(const void *b1, const void *b2) static voidpf inflate_malloc(voidpf opaque, uInt items, uInt size) { - return malloc(items*size); + return calloc(items*size, sizeof(uint8_t)); } @@ -1038,8 +1038,11 @@ static bool shrink_key_space(float *brute_forces) } *brute_forces = MIN(brute_forces1, brute_forces2); float reduction_rate = update_reduction_rate(*brute_forces, false); - return ((hardnested_stage & CHECK_2ND_BYTES) - && reduction_rate >= 0.0 && reduction_rate < brute_force_per_second * sample_period / 1000.0); + +//iceman 2018 + return ((hardnested_stage & CHECK_2ND_BYTES) && + reduction_rate >= 0.0 && + ( reduction_rate < brute_force_per_second * (float)sample_period / 1000.0 || *brute_forces < 0x1F000000000)); } diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index b5be04593..e583f7f02 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -980,11 +980,11 @@ int CmdHF14AMfUInfo(const char *Cmd){ if ( hasAuthKey ) return 1; // also try to diversify default keys.. look into CmdHF14AMfuGenDiverseKeys - PrintAndLogEx(NORMAL, "Trying some default 3des keys"); + PrintAndLogEx(INFO, "Trying some default 3des keys"); for (uint8_t i = 0; i < KEYS_3DES_COUNT; ++i ) { key = default_3des_keys[i]; if (ulc_authentication(key, true)) { - PrintAndLogEx(NORMAL, "Found default 3des key: "); + PrintAndLogEx(SUCCESS, "Found default 3des key: "); uint8_t keySwap[16]; memcpy(keySwap, SwapEndian64(key,16,8), 16); ulc_print_3deskey(keySwap); @@ -1079,7 +1079,7 @@ int CmdHF14AMfUInfo(const char *Cmd){ num_to_bytes( ul_ev1_pwdgenA(card.uid), 4, key); len = ulev1_requestAuthentication(key, pack, sizeof(pack)); if (len > -1) { - PrintAndLogEx(NORMAL, "Found a default password: %s || Pack: %02X %02X",sprint_hex(key, 4), pack[0], pack[1]); + PrintAndLogEx(SUCCESS, "Found a default password: %s || Pack: %02X %02X",sprint_hex(key, 4), pack[0], pack[1]); goto out; } @@ -1089,7 +1089,7 @@ int CmdHF14AMfUInfo(const char *Cmd){ num_to_bytes( ul_ev1_pwdgenB(card.uid), 4, key); len = ulev1_requestAuthentication(key, pack, sizeof(pack)); if (len > -1) { - PrintAndLogEx(NORMAL, "Found a default password: %s || Pack: %02X %02X",sprint_hex(key, 4), pack[0], pack[1]); + PrintAndLogEx(SUCCESS, "Found a default password: %s || Pack: %02X %02X",sprint_hex(key, 4), pack[0], pack[1]); goto out; } @@ -1099,7 +1099,7 @@ int CmdHF14AMfUInfo(const char *Cmd){ num_to_bytes( ul_ev1_pwdgenC(card.uid), 4, key); len = ulev1_requestAuthentication(key, pack, sizeof(pack)); if (len > -1) { - PrintAndLogEx(NORMAL, "Found a default password: %s || Pack: %02X %02X",sprint_hex(key, 4), pack[0], pack[1]); + PrintAndLogEx(SUCCESS, "Found a default password: %s || Pack: %02X %02X",sprint_hex(key, 4), pack[0], pack[1]); goto out; } @@ -1109,7 +1109,7 @@ int CmdHF14AMfUInfo(const char *Cmd){ num_to_bytes( ul_ev1_pwdgenD(card.uid), 4, key); len = ulev1_requestAuthentication(key, pack, sizeof(pack)); if (len > -1) { - PrintAndLogEx(NORMAL, "Found a default password: %s || Pack: %02X %02X",sprint_hex(key, 4), pack[0], pack[1]); + PrintAndLogEx(SUCCESS, "Found a default password: %s || Pack: %02X %02X",sprint_hex(key, 4), pack[0], pack[1]); goto out; } @@ -1119,13 +1119,13 @@ int CmdHF14AMfUInfo(const char *Cmd){ key = default_pwd_pack[i]; len = ulev1_requestAuthentication(key, pack, sizeof(pack)); if (len > -1) { - PrintAndLogEx(NORMAL, "Found a default password: %s || Pack: %02X %02X",sprint_hex(key, 4), pack[0], pack[1]); + PrintAndLogEx(SUCCESS, "Found a default password: %s || Pack: %02X %02X",sprint_hex(key, 4), pack[0], pack[1]); break; } else { if (!ul_auth_select( &card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack))) return -1; } } - if (len < 1) PrintAndLogEx(NORMAL, "password not known"); + if (len < 1) PrintAndLogEx(WARNING, "password not known"); } } out: @@ -1250,7 +1250,7 @@ int CmdHF14AMfUWrBl(const char *Cmd){ UsbCommand resp; if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { uint8_t isOK = resp.arg[0] & 0xff; - PrintAndLogEx(NORMAL, "isOk:%02x", isOK); + PrintAndLogEx(SUCCESS, "isOk:%02x", isOK); } else { PrintAndLogEx(WARNING, "Command execute timeout"); } @@ -1365,7 +1365,7 @@ int CmdHF14AMfURdBl(const char *Cmd){ PrintAndLogEx(WARNING, "Failed reading block: (%02x)", isOK); } } else { - PrintAndLogEx(NORMAL, "Command execute time-out"); + PrintAndLogEx(WARNING, "Command execute time-out"); } return 0; } @@ -1743,7 +1743,7 @@ int CmdHF14AMfUDump(const char *Cmd){ } } ul_print_type(tagtype, 0); - PrintAndLogEx(NORMAL, "Reading tag memory..."); + PrintAndLogEx(SUCCESS, "Reading tag memory..."); UsbCommand c = {CMD_MIFAREU_READCARD, {startPage, pages}}; if ( hasAuthKey ) { if (tagtype & UL_C) @@ -1912,12 +1912,10 @@ int CmdHF14AMfURestore(const char *Cmd){ memset(authkey, 0x00, sizeof(authkey)); while(param_getchar(Cmd, cmdp) != 0x00 && !errors) { - switch(param_getchar(Cmd, cmdp)) { + switch (tolower(param_getchar(Cmd, cmdp))) { case 'h': - case 'H': return usage_hf_mfu_restore(); case 'k': - case 'K': keylen = param_getstr(Cmd, cmdp+1, tempStr, sizeof(tempStr)); if (keylen == 32 || keylen == 8) { //ul-c or ev1/ntag key length errors = param_gethex(tempStr, 0, authkey, keylen); @@ -1930,12 +1928,10 @@ int CmdHF14AMfURestore(const char *Cmd){ hasKey = true; break; case 'l': - case 'L': swapEndian = true; cmdp++; break; case 'f': - case 'F': filelen = param_getstr(Cmd, cmdp+1, filename, FILE_PATH_SIZE); if (filelen > FILE_PATH_SIZE-5) @@ -1947,17 +1943,14 @@ int CmdHF14AMfURestore(const char *Cmd){ cmdp += 2; break; case 's': - case 'S': cmdp++; write_special = true; break; case 'e': - case 'E': cmdp++; write_extra = true; break; case 'r': - case 'R': cmdp++; read_key = true; break; @@ -1972,7 +1965,7 @@ int CmdHF14AMfURestore(const char *Cmd){ if (errors || cmdp == 0) return usage_hf_mfu_restore(); if ((f = fopen(filename,"rb")) == NULL) { - PrintAndLogEx(WARNING, "Could not find file %s", filename); + PrintAndLogEx(WARNING, "Could not find file " _YELLOW_(%s), filename); return 1; } @@ -2000,7 +1993,7 @@ int CmdHF14AMfURestore(const char *Cmd){ return 1; } - PrintAndLogEx(NORMAL, "Restoring %s to card", filename); + PrintAndLogEx(INFO, "Restoring " _YELLOW_(%s)" to card", filename); mfu_dump_t *mem = (mfu_dump_t*)dump; uint8_t pages = (bytes_read-48)/4; @@ -2084,7 +2077,7 @@ int CmdHF14AMfURestore(const char *Cmd){ } } - PrintAndLogEx(NORMAL, "Restoring data blocks."); + PrintAndLogEx(INFO, "Restoring data blocks."); // write all other data // Skip block 0,1,2,3 (only magic tags can write to them) // Skip last 5 blocks usually is configuration @@ -2103,7 +2096,7 @@ int CmdHF14AMfURestore(const char *Cmd){ // write special data last if (write_special) { - PrintAndLogEx(NORMAL, "Restoring configuration blocks.\n"); + PrintAndLogEx(INFO, "Restoring configuration blocks.\n"); PrintAndLogEx(NORMAL, "authentication with keytype[%x] %s\n", (uint8_t)(c.arg[1] & 0xff), sprint_hex(p_authkey,4)); @@ -2128,16 +2121,16 @@ int CmdHF14AMfURestore(const char *Cmd){ // Load emulator with dump file // int CmdHF14AMfUeLoad(const char *Cmd){ - char c = param_getchar(Cmd, 0); - if ( c == 'h' || c == 'H' || c == 0x00) return usage_hf_mfu_eload(); + char c = tolower(param_getchar(Cmd, 0)); + if ( c == 'h' || c == 0x00) return usage_hf_mfu_eload(); return CmdHF14AMfELoad(Cmd); } // // Simulate tag // int CmdHF14AMfUSim(const char *Cmd){ - char c = param_getchar(Cmd, 0); - if ( c == 'h' || c == 'H' || c == 0x00) return usage_hf_mfu_sim(); + char c = tolower(param_getchar(Cmd, 0)); + if ( c == 'h' || c == 0x00) return usage_hf_mfu_sim(); return CmdHF14ASim(Cmd); } @@ -2153,16 +2146,16 @@ int CmdHF14AMfucAuth(const char *Cmd){ uint8_t keyNo = 3; bool errors = false; - char cmdp = param_getchar(Cmd, 0); + char cmdp = tolower(param_getchar(Cmd, 0)); //Change key to user defined one - if (cmdp == 'k' || cmdp == 'K'){ + if (cmdp == 'k'){ keyNo = param_get8(Cmd, 1); if(keyNo >= KEYS_3DES_COUNT) errors = true; } - if (cmdp == 'h' || cmdp == 'H') errors = true; + if (cmdp == 'h') errors = true; if (errors) return usage_hf_mfu_ucauth(); @@ -2278,9 +2271,9 @@ int CmdTestDES(const char * cmd) int CmdHF14AMfucSetPwd(const char *Cmd){ uint8_t pwd[16] = {0x00}; - char cmdp = param_getchar(Cmd, 0); + char cmdp = tolower(param_getchar(Cmd, 0)); - if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_hf_mfu_ucsetpwd(); + if (strlen(Cmd) == 0 || cmdp == 'h') return usage_hf_mfu_ucsetpwd(); if (param_gethex(Cmd, 0, pwd, 32)) { PrintAndLogEx(WARNING, "Password must include 32 HEX symbols"); @@ -2295,7 +2288,7 @@ int CmdHF14AMfucSetPwd(const char *Cmd){ UsbCommand resp; if (WaitForResponseTimeout(CMD_ACK,&resp,1500) ) { if ( (resp.arg[0] & 0xff) == 1) { - PrintAndLogEx(NORMAL, "Ultralight-C new password: %s", sprint_hex(pwd,16)); + PrintAndLogEx(INFO, "Ultralight-C new password: %s", sprint_hex(pwd,16)); } else { PrintAndLogEx(WARNING, "Failed writing at block %d", resp.arg[1] & 0xff); return 1; @@ -2315,9 +2308,9 @@ int CmdHF14AMfucSetUid(const char *Cmd){ UsbCommand c = {CMD_MIFAREU_READBL}; UsbCommand resp; uint8_t uid[7] = {0x00}; - char cmdp = param_getchar(Cmd, 0); + char cmdp = tolower(param_getchar(Cmd, 0)); - if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_hf_mfu_ucsetuid(); + if (strlen(Cmd) == 0 || cmdp == 'h') return usage_hf_mfu_ucsetuid(); if (param_gethex(Cmd, 0, uid, 14)) { PrintAndLogEx(WARNING, "UID must include 14 HEX symbols"); diff --git a/client/cmdhftopaz.c b/client/cmdhftopaz.c index ea4699f1b..2f80b054c 100644 --- a/client/cmdhftopaz.c +++ b/client/cmdhftopaz.c @@ -194,7 +194,7 @@ static int topaz_print_CC(uint8_t *data) { PrintAndLogEx(NORMAL, " %02x: version %d.%d supported by tag", data[1], (data[1] & 0xF0) >> 4, data[1] & 0x0f); uint16_t memsize = (data[2] + 1) * 8; topaz_tag.size = memsize; - topaz_tag.dynamic_memory = malloc(memsize - TOPAZ_STATIC_MEMORY); + topaz_tag.dynamic_memory = calloc(memsize - TOPAZ_STATIC_MEMORY, sizeof(uint8_t)); PrintAndLogEx(NORMAL, " %02x: Physical Memory Size of this tag: %d bytes", data[2], memsize); PrintAndLogEx(NORMAL, " %02x: %s / %s", data[3], (data[3] & 0xF0) ? "(RFU)" : "Read access granted without any security", @@ -278,12 +278,12 @@ static void topaz_print_control_TLVs(uint8_t *memory) { dynamic_lock_area_t *old = topaz_tag.dynamic_lock_areas; dynamic_lock_area_t *new = topaz_tag.dynamic_lock_areas; if (old == NULL) { - new = topaz_tag.dynamic_lock_areas = (dynamic_lock_area_t *)malloc(sizeof(dynamic_lock_area_t)); + new = topaz_tag.dynamic_lock_areas = (dynamic_lock_area_t *) calloc(sizeof(dynamic_lock_area_t) , sizeof(uint8_t)); } else { while(old->next != NULL) { old = old->next; } - new = old->next = (dynamic_lock_area_t *)malloc(sizeof(dynamic_lock_area_t)); + new = old->next = (dynamic_lock_area_t *) calloc(sizeof(dynamic_lock_area_t), sizeof(uint8_t)); } new->next = NULL; if (area_start <= next_lockable_byte) { diff --git a/client/cmdhw.c b/client/cmdhw.c index a93a940cc..ec7b42a1a 100644 --- a/client/cmdhw.c +++ b/client/cmdhw.c @@ -257,9 +257,9 @@ int CmdVersion(const char *Cmd) { SendCommand(&c); if (WaitForResponseTimeout(CMD_ACK, &resp, 1000)) { #ifdef __WIN32 - PrintAndLogEx(NORMAL, "\nProxmark3 RFID instrument\n"); + PrintAndLogEx(NORMAL, "\n [ Proxmark3 RFID instrument ]\n"); #else - PrintAndLogEx(NORMAL, "\n\e[34mProxmark3 RFID instrument\e[0m\n"); + PrintAndLogEx(NORMAL, "\n\e[34m [ Proxmark3 RFID instrument ]\e[0m\n"); #endif char s[50] = {0}; #if defined(WITH_FLASH) || defined(WITH_SMARTCARD) || defined(WITH_FPC) @@ -275,7 +275,7 @@ int CmdVersion(const char *Cmd) { strncat(s, "fpc; ", sizeof(s) - strlen(s) - 1); #endif PrintAndLogEx(NORMAL, "\n [ CLIENT ]"); - PrintAndLogEx(NORMAL, " client: iceman %s \n", s); + PrintAndLogEx(NORMAL, " client: iceman %s \n", s); PrintAndLogEx(NORMAL, (char*)resp.d.asBytes); lookupChipID(resp.arg[0], resp.arg[1]); diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index ed8c0464e..abf8f04ec 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -141,21 +141,33 @@ int usage_t55xx_wakup(){ PrintAndLogEx(NORMAL, " lf t55xx wakeup p 11223344 - send wakeup password"); return 0; } -int usage_t55xx_bruteforce(){ - PrintAndLogEx(NORMAL, "This command uses A) bruteforce to scan a number range"); - PrintAndLogEx(NORMAL, " B) a dictionary attack"); +int usage_t55xx_chk(){ + PrintAndLogEx(NORMAL, "This command uses a dictionary attack"); PrintAndLogEx(NORMAL, "press 'enter' to cancel the command"); - PrintAndLogEx(NORMAL, "Usage: lf t55xx bruteforce [h] [i <*.dic>]"); + PrintAndLogEx(NORMAL, "Usage: lf t55xx bruteforce [h] [i <*.dic>]"); + PrintAndLogEx(NORMAL, "Options:"); + PrintAndLogEx(NORMAL, " h - this help"); + PrintAndLogEx(NORMAL, " m - use dictionary from flashmemory\n"); + PrintAndLogEx(NORMAL, " i <*.dic> - loads a default keys dictionary file <*.dic>"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Examples:"); + PrintAndLogEx(NORMAL, " lf t55xx bruteforce m"); + PrintAndLogEx(NORMAL, " lf t55xx bruteforce i default_pwd.dic"); + PrintAndLogEx(NORMAL, ""); + return 0; +} +int usage_t55xx_bruteforce(){ + PrintAndLogEx(NORMAL, "This command uses bruteforce to scan a number range"); + PrintAndLogEx(NORMAL, "press 'enter' to cancel the command"); + PrintAndLogEx(NORMAL, "Usage: lf t55xx bruteforce [h] "); PrintAndLogEx(NORMAL, " password must be 4 bytes (8 hex symbols)"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h - this help"); PrintAndLogEx(NORMAL, " - 4 byte hex value to start pwd search at"); PrintAndLogEx(NORMAL, " - 4 byte hex value to end pwd search at"); - PrintAndLogEx(NORMAL, " i <*.dic> - loads a default keys dictionary file <*.dic>"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx bruteforce aaaaaaaa bbbbbbbb"); - PrintAndLogEx(NORMAL, " lf t55xx bruteforce i default_pwd.dic"); PrintAndLogEx(NORMAL, ""); return 0; } @@ -224,10 +236,9 @@ int CmdT55xxSetConfig(const char *Cmd) { uint8_t cmdp = 0; bool errors = false; while(param_getchar(Cmd, cmdp) != 0x00 && !errors) { - tmp = param_getchar(Cmd, cmdp); + tmp = tolower(param_getchar(Cmd, cmdp)); switch(tmp) { case 'h': - case 'H': return usage_t55xx_config(); case 'b': errors |= param_getdec(Cmd, cmdp+1, &bitRate); @@ -292,12 +303,10 @@ int CmdT55xxSetConfig(const char *Cmd) { config.offset = offset; cmdp+=2; break; - case 'Q': case 'q': config.Q5 = true; cmdp++; break; - case 'S': case 's': config.ST = true; cmdp++; @@ -343,8 +352,8 @@ int T55xxReadBlock(uint8_t block, bool page1, bool usepwd, bool override, uint32 if (!AquireData(page1, block, usepwd, password) ) return 0; if (!DecodeT55xxBlock()) return 0; - char blk[10]={0}; - sprintf(blk,"%02d", block); + char blk[10] = {0}; + sprintf(blk, "%02d", block); printT55xxBlock(blk); return 1; } @@ -358,22 +367,18 @@ int CmdT55xxReadBlock(const char *Cmd) { bool errors = false; uint8_t cmdp = 0; while(param_getchar(Cmd, cmdp) != 0x00 && !errors) { - switch(param_getchar(Cmd, cmdp)) { + switch ( tolower(param_getchar(Cmd, cmdp))) { case 'h': - case 'H': return usage_t55xx_read(); case 'b': - case 'B': errors |= param_getdec(Cmd, cmdp+1, &block); cmdp += 2; break; case 'o': - case 'O': override = true; cmdp++; break; case 'p': - case 'P': password = param_get32ex(Cmd, cmdp+1, 0, 16); usepwd = true; cmdp += 2; @@ -1503,23 +1508,68 @@ bool IsCancelled(void) { return false; } -int CmdT55xxBruteForce(const char *Cmd) { - +int CmdT55xxChkPwds(const char *Cmd) { // load a default pwd file. char line[9]; char filename[FILE_PATH_SIZE] = {0}; int keycnt = 0; uint8_t stKeyBlock = 20; uint8_t *keyBlock = NULL, *p = NULL; - uint32_t start_password = 0x00000000; //start password - uint32_t end_password = 0xFFFFFFFF; //end password bool found = false; + uint8_t timeout = 0; memset(line, 0, sizeof(line)); char cmdp = tolower(param_getchar(Cmd, 0)); - if (cmdp == 'h') return usage_t55xx_bruteforce(); + if (cmdp == 'h') return usage_t55xx_chk(); + + /* + if ( T55xxReadBlock(7, 0, 0, 0, 0) ) { + + // now try to validate it.. + PrintAndLogEx(WARNING, "\n Block 7 was readable"); + return 1; + } + */ + + uint64_t t1 = msclock(); + if ( cmdp == 'm' ) { + UsbCommand c = {CMD_T55XX_CHKPWDS, {0,0,0} }; + clearCommandBuffer(); + SendCommand(&c); + UsbCommand resp; + + while ( !WaitForResponseTimeout(CMD_ACK, &resp, 2000) ) { + timeout++; + printf("."); fflush(stdout); + if (timeout > 180) { + PrintAndLogEx(WARNING, "\nno response from Proxmark. Aborting..."); + return 2; + } + } + + if ( resp.arg[0] ) { + PrintAndLogEx(SUCCESS, "\nFound a candidate [ %08X ]. Trying to validate", resp.arg[1]); + + if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, resp.arg[1])) { + PrintAndLogEx(INFO, "Aquireing data from device failed. Quitting"); + return 2; + } + + found = tryDetectModulation(); + if (found) { + PrintAndLogEx(SUCCESS, "Found valid password: [ %08X ]", resp.arg[1]); + } else { + PrintAndLogEx(WARNING, "Password NOT found."); + } + } else { + PrintAndLogEx(WARNING, "Password NOT found."); + } + + goto out; + } + keyBlock = calloc(stKeyBlock, 4); if (keyBlock == NULL) return 1; @@ -1531,7 +1581,7 @@ int CmdT55xxBruteForce(const char *Cmd) { FILE * f = fopen( filename , "r"); if ( !f ) { - PrintAndLogEx(NORMAL, "File: %s: not found or locked.", filename); + PrintAndLogEx(WARNING, "File: %s: not found or locked.", filename); free(keyBlock); return 1; } @@ -1546,7 +1596,7 @@ int CmdT55xxBruteForce(const char *Cmd) { if( line[0]=='#' ) continue; if (!isxdigit(line[0])) { - PrintAndLogEx(NORMAL, "File content error. '%s' must include 8 HEX symbols", line); + PrintAndLogEx(WARNING, "File content error. '%s' must include 8 HEX symbols", line); continue; } @@ -1569,7 +1619,7 @@ int CmdT55xxBruteForce(const char *Cmd) { num_to_bytes( strtoll(line, NULL, 16), 4, keyBlock + 4*keycnt); - PrintAndLogEx(NORMAL, "chk custom pwd[%2d] %08X", keycnt, bytes_to_num(keyBlock + 4 * keycnt, 4) ); +// PrintAndLogEx(NORMAL, "chk custom pwd[%2d] %08X", keycnt, bytes_to_num(keyBlock + 4 * keycnt, 4) ); keycnt++; memset(line, 0, sizeof(line)); } @@ -1577,11 +1627,11 @@ int CmdT55xxBruteForce(const char *Cmd) { fclose(f); if (keycnt == 0) { - PrintAndLogEx(NORMAL, "No keys found in file"); + PrintAndLogEx(WARNING, "No keys found in file"); free(keyBlock); return 1; } - PrintAndLogEx(NORMAL, "Loaded %d keys", keycnt); + PrintAndLogEx(SUCCESS, "Loaded %d keys", keycnt); // loop uint64_t testpwd = 0x00; @@ -1600,69 +1650,87 @@ int CmdT55xxBruteForce(const char *Cmd) { testpwd = bytes_to_num(keyBlock + 4*c, 4); - PrintAndLogEx(NORMAL, "Testing %08X", testpwd); + PrintAndLogEx(INFO, "Testing %08X", testpwd); if ( !AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, testpwd)) { - PrintAndLogEx(NORMAL, "Aquireing data from device failed. Quitting"); + PrintAndLogEx(INFO, "Aquireing data from device failed. Quitting"); free(keyBlock); return 0; } found = tryDetectModulation(); - if ( found ) { - PrintAndLogEx(NORMAL, "Found valid password: [%08X]", testpwd); - //free(keyBlock); - //return 0; - } + if ( found ) + break; + } - PrintAndLogEx(NORMAL, "Password NOT found."); - free(keyBlock); - return 0; + if ( found ) + PrintAndLogEx(SUCCESS, "Found valid password: [ %08X ]", testpwd); + else + PrintAndLogEx(WARNING, "Password NOT found."); } + free(keyBlock); + +out: + t1 = msclock() - t1; + PrintAndLogEx(SUCCESS, "\nTime in bruteforce: %.0f seconds\n", (float)t1/1000.0); + return 0; +} + +int CmdT55xxBruteForce(const char *Cmd) { + + uint32_t start_password = 0x00000000; //start password + uint32_t end_password = 0xFFFFFFFF; //end password + uint32_t curr = 0; + bool found = false; + + + char cmdp = tolower(param_getchar(Cmd, 0)); + if (cmdp == 'h') return usage_t55xx_bruteforce(); + + uint64_t t1 = msclock(); + // Try to read Block 7, first :) // incremental pwd range search start_password = param_get32ex(Cmd, 0, 0, 16); end_password = param_get32ex(Cmd, 1, 0, 16); + curr = start_password; + if ( start_password >= end_password ) { - free(keyBlock); return usage_t55xx_bruteforce(); } - PrintAndLogEx(NORMAL, "Search password range [%08X -> %08X]", start_password, end_password); - - uint32_t i = start_password; + PrintAndLogEx(INFO, "Search password range [%08X -> %08X]", start_password, end_password); - while ((!found) && (i <= end_password)){ + while ((!found) || (curr <= end_password)){ printf("."); fflush(stdout); if (IsCancelled()) { - free(keyBlock); return 0; } - if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, i)) { - PrintAndLogEx(NORMAL, "Aquireing data from device failed. Quitting"); - free(keyBlock); + if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, curr)) { + PrintAndLogEx(WARNING, "Aquireing data from device failed. Quitting"); return 0; } found = tryDetectModulation(); if (found) break; - i++; + ++curr; } PrintAndLogEx(NORMAL, ""); if (found) - PrintAndLogEx(NORMAL, "Found valid password: [%08x]", i); + PrintAndLogEx(SUCCESS, "Found valid password: [ %08X ]", curr); else - PrintAndLogEx(NORMAL, "Password NOT found. Last tried: [%08x]", --i); + PrintAndLogEx(WARNING, "Password NOT found. Last tried: [ %08X ]", --curr); - free(keyBlock); + t1 = msclock() - t1; + PrintAndLogEx(SUCCESS, "\nTime in bruteforce: %.0f seconds\n", (float)t1/1000.0); return 0; } @@ -1746,9 +1814,9 @@ int CmdT55xxRecoverPW(const char *Cmd) { PrintAndLogEx(NORMAL, ""); if (found == 1) - PrintAndLogEx(NORMAL, "Found valid password: [%08x]", curr_password); + PrintAndLogEx(SUCCESS, "Found valid password: [%08x]", curr_password); else - PrintAndLogEx(NORMAL, "Password NOT found."); + PrintAndLogEx(WARNING, "Password NOT found."); return 0; } @@ -1959,6 +2027,7 @@ static command_t CommandTable[] = { {"help", CmdHelp, 1, "This help"}, {"bruteforce", CmdT55xxBruteForce,0, " [i <*.dic>] Simple bruteforce attack to find password"}, {"config", CmdT55xxSetConfig, 1, "Set/Get T55XX configuration (modulation, inverted, offset, rate)"}, + {"chk", CmdT55xxChkPwds, 1, "Check passwords"}, {"detect", CmdT55xxDetect, 1, "[1] Try detecting the tag modulation from reading the configuration block."}, {"deviceconfig", CmdT55xxSetDeviceConfig, 1, "Set/Get T55XX device configuration (startgap, writegap, write0, write1, readgap"}, {"p1detect", CmdT55xxDetectPage1,1, "[1] Try detecting if this is a t55xx tag by reading page 1"}, diff --git a/client/cmdlft55xx.h b/client/cmdlft55xx.h index 15adab0b6..46de0c359 100644 --- a/client/cmdlft55xx.h +++ b/client/cmdlft55xx.h @@ -133,6 +133,7 @@ t55xx_conf_block_t Get_t55xx_Config(void); void Set_t55xx_Config(t55xx_conf_block_t conf); extern int CmdLFT55XX(const char *Cmd); +extern int CmdT55xxChk(const char *Cmd); extern int CmdT55xxBruteForce(const char *Cmd); extern int CmdT55xxSetConfig(const char *Cmd); extern int CmdT55xxReadBlock(const char *Cmd); diff --git a/client/cmdsmartcard.c b/client/cmdsmartcard.c index fdc825d38..23b2b8b3c 100644 --- a/client/cmdsmartcard.c +++ b/client/cmdsmartcard.c @@ -356,7 +356,7 @@ static int smart_responseEx(uint8_t *data, bool silent) { if (needGetData) { int len = data[datalen - 1]; if (!silent) PrintAndLogEx(INFO, "Requesting 0x%02X bytes response", len); - uint8_t getstatus[] = {0x00, ISO7816_GETSTATUS, 0x00, 0x00, len}; + uint8_t getstatus[] = {0x00, ISO7816_GET_RESPONSE, 0x00, 0x00, len}; UsbCommand cStatus = {CMD_SMART_RAW, {SC_RAW, sizeof(getstatus), 0}}; memcpy(cStatus.d.asBytes, getstatus, sizeof(getstatus) ); clearCommandBuffer(); @@ -372,7 +372,7 @@ static int smart_responseEx(uint8_t *data, bool silent) { if (datalen != len + 2) { // data with ACK if (datalen == len + 2 + 1) { // 2 - response, 1 - ACK - if (data[0] != ISO7816_GETSTATUS) { + if (data[0] != ISO7816_GET_RESPONSE) { if (!silent) { PrintAndLogEx(ERR, "GetResponse ACK error. len 0x%x | data[0] %02X", len, data[0]); } @@ -1012,7 +1012,7 @@ int CmdSmartBruteforceSFI(const char *Cmd) { json_t *root = NULL; smart_loadjson("aidlist", "json", &root); - uint8_t* buf = malloc(USB_CMD_DATA_SIZE); + uint8_t* buf = calloc(USB_CMD_DATA_SIZE, sizeof(uint8_t)); if ( !buf ) return 1; diff --git a/client/default_keys.dic b/client/default_keys.dic index 3fb8f07bf..ffbdb3cbd 100644 --- a/client/default_keys.dic +++ b/client/default_keys.dic @@ -711,4 +711,47 @@ FD8705E721B0, 00ada2cd516d, # # -D3F7D3F7D3F7 \ No newline at end of file +D3F7D3F7D3F7 +## +237a4d0d9119, +0ed7846c2bc9, +FFFFD06F83E3, +FFFFAE82366C, +F89C86B2A961, +F83466888612, +ED3A7EFBFF56, +E96246531342, +E1DD284379D4, +DFED39FFBB76, +DB5181C92CBE, +CFC738403AB0, +BCFE01BCFE01, +BA28CFD15EE8, +B0699AD03D17, +AABBCC660429, +A4EF6C3BB692, +A2B2C9D187FB, +9B1DD7C030A1, +9AEDF9931EC1, +8F9B229047AC, +872B71F9D15A, +833FBD3CFE51, +5D293AFC8D7E, +5554AAA96321, +474249437569, +435330666666, +1A2B3C4D5E6F, +123456ABCDEF, +83BAB5ACAD62, +64E2283FCF5E, +64A2EE93B12B, +46868F6D5677, +40E5EA1EFC00, +37D4DCA92451, +2012053082AD, +2011092119F1, +200306202033, +1795902DBAF9, +17505586EF02, +022FE48B3072, +013940233313, diff --git a/client/default_pwd.dic b/client/default_pwd.dic index dd1364385..87423478b 100644 --- a/client/default_pwd.dic +++ b/client/default_pwd.dic @@ -96,6 +96,7 @@ FABADA11, //china? 69696969, 12121212, 12344321, +1234ABCD, 11112222, 13131313, 10041004, @@ -104,8 +105,8 @@ FABADA11, //china? abcd1234, 20002000, 19721972, -aa55aa55, //amiboo -55aa55aa, //rev amiboo +aa55aa55, // amiboo +55aa55aa, // rev amiboo 4f271149, // seeds ul-ev1 07d7bb0b, // seeds ul-ev1 9636ef8f, // seeds ul-ev1 @@ -113,4 +114,4 @@ b5f44686, // seeds ul-ev1 9E3779B9, // TEA C6EF3720, // TEA 7854794A, // xbox tea constant :) -F1EA5EED, //burtle +F1EA5EED, // burtle diff --git a/client/dictionaries/bmp_sort_keys.dic b/client/dictionaries/bmp_sort_keys.dic new file mode 100644 index 000000000..0f8acdcf3 --- /dev/null +++ b/client/dictionaries/bmp_sort_keys.dic @@ -0,0 +1,1000 @@ +002DE0301481, +004173272D18, +0058A4884CA5, +00BAC32761D8, +00BB79731B00, +00E8C85DB172, +02096124DA70, +024988BC4D5E, +0271B7C4B015, +028137A705DB, +02827C286AB4, +02C10DA600D0, +0340643D5E27, +037A5DA4682B, +037AC43CBD9D, +037B9B8AA219, +037EE3DE21B7, +0380A9A3CBDE, +03D10A75B56A, +03E8CD22E691, +04109ED8EA79, +04361330B35C, +043D8B66D569, +045E5588845C, +048DE5148DE7, +0490921D0194, +04B717BD92EB, +04D49C76623B, +051518B3301E, +0529E8827A52, +052B16064085, +05DC4016B500, +06124317A9A6, +06147D199266, +0670AEB833CE, +0686A9E6D6E0, +06A34E5E6639, +06B78AD0C4BB, +0710E7818AB8, +07121B8C633A, +07176713C0ED, +0793533A5087, +081D1B1C3110, +0849495E1CCA, +09429512046E, +0966C3B28E04, +098A92C3660A, +098B48278122, +099672009EEA, +0A7632943926, +0AEE126549DA, +0B3B8C2833BC, +0B733C13E2C9, +0B764247D00E, +0BE811559D69, +0C208AD4E4B3, +0C270BC0BDDC, +0C5D782CB183, +0C82C94EB11B, +0CCDE948878A, +0CCE39820AAE, +0CDE3E716B32, +0CE06C96DB4C, +0CE87813E389, +0D3385CEA152, +0D5C5B8BCC5B, +0DB0A87AB882, +0DE247593B93, +0E0AD1796003, +0E62E6CAC3D3, +106E2D6E55E6, +1096A7830C82, +11549C141AD9, +116A92C793D6, +116C31526819, +11C68052AAE9, +1234B5BE8E78, +1268C7D104E1, +12A21B5671A8, +13359D5AE9A5, +1426EC62BB6C, +144489B1056E, +14A22C112090, +14C9BBB5361B, +14EB6286AC57, +14EE72B27223, +153BB53ACE71, +157B03405B38, +15A45083D24E, +15DACCE8D5EC, +16124677BBC5, +16373A44D5D7, +1663659384DC, +167828B6105C, +16B25A453093, +1706B1BE25C7, +171B15888483, +17BC8EED9A0C, +17C6299D5A37, +17E9C4C416EB, +1804087C7166, +1841CC4E3E79, +18AB05761CC5, +18ADAAC2B08B, +18E566417E5C, +191390328752, +1A47959E7DB4, +1A9A970CC370, +1B095E78BB33, +1B1717043D2B, +1B1A054566D9, +1B4654AE9454, +1B9CD1ED3420, +1B9E00780953, +1BB6A9CE71E2, +1C1250A36A13, +1C2316079532, +1C2855ED7A10, +1CD1AE73CA8C, +1CD3D4E690B7, +1D0322005969, +1D09B23EB116, +1D67A32045ED, +1D89D900968A, +1DAE8D2CEA5C, +1E1873799CD7, +1E60CE7C5179, +1E6A67909B8D, +1E8516585792, +1EB0864E9134, +1ECE3D04A020, +2009828E4A21, +200A6A3AA65D, +20188A599582, +20267CB20256, +20628CA7D92D, +2077C980EB2E, +2089B5D68B27, +209481EC6256, +20B6691C64B1, +20CC5A00C677, +211473555436, +2170E9D0D448, +219529A90EDD, +21A5B6481B7D, +224A308017D1, +227D16EA455A, +22A1245CA266, +22A95CB798DC, +230E26964171, +231173B68E46, +2332BB9A2452, +234323BC2992, +234E50256146, +235C9338D5B6, +23789D9ADD0D, +23997DD240AB, +23A5BA53AD4D, +23BB58853461, +24CAD4153036, +24CE79506842, +25228ED714BC, +257377227B34, +2584287A0174, +2616192EEB22, +265C03B50877, +26D641E834DC, +27073B57132B, +279060E3DEE9, +284BA0A0A29C, +285C6604C5B4, +28B20331245A, +28D042242A83, +28DDD4C3E9C4, +292C2CCD157E, +299ABB519354, +2A41BE015C1D, +2A4A55052A51, +2A94CBCD7A6E, +2AB6536187C7, +2B2D2DC3D319, +2BD607CA70B2, +2C6C7957EB3E, +2C9E9E4D0895, +2D2A97DD45E3, +2D41850A8AA6, +2DAC030D1AB9, +2E12426D8847, +2E25AD1D6D8D, +2E2E85E0E6C9, +2E4340CC1C63, +2E6803BE2E11, +2EB24B573DCD, +2EC6450A47C7, +2ECDA9A5EA96, +2EDE1C155023, +302D5D37342B, +303645E47667, +303B30A460E8, +3048EBB8A18E, +30BD652BED24, +30CCE5ECB397, +310241E1CB36, +312670228372, +319E8895EAB5, +31E3A933BC4A, +3250D2E661DA, +32560224418D, +32589E221D10, +326657A8E9C0, +329AC7C59311, +32A091B89995, +3312C094BD20, +336C8CBA5AE2, +34240649314A, +3493D84E6317, +349A347186D7, +349BEAC5210E, +34A939B49EDC, +34CC7E36C8C4, +34D71347877E, +34DC25B4D0CE, +35895EB472C4, +358A6A398211, +360A08C66042, +36306A9CA571, +37284428A250, +377EC8A78B8D, +37BD90A68613, +37E602347133, +382DE6AB2D1A, +385D498B5390, +38B67589E47D, +393CCCCCDA4A, +39682B3E10B5, +397619525709, +39A83A32909B, +3A5834C46513, +3A70C7A4BCE4, +3A818D01E093, +3AA5AC1CDC21, +3AAE07339954, +3B4497052B42, +3B784087DB2D, +3B86A20C16EA, +3B8E321AB1B4, +3BC4A3099B0D, +3BC741376E71, +3C4C95D0A0C7, +3C84B55A5E54, +3C888A88C59D, +3D5C8240B2D2, +3DB004172BE7, +3E23271C1C15, +3E3188294ED1, +3E84144A770E, +3EA227893101, +3EB914E70076, +3EE6D4A85643, +40DABA780B41, +4119340759A2, +415210E0C6BB, +416D21717779, +41B1839829A9, +4201A36DE766, +4261A795D5A7, +42AA0B29626E, +430265958BEB, +4317C5C16EAD, +431D799E0C89, +4342794AD7BB, +4387ADE263DB, +43982124C310, +4436CB060568, +44449507B736, +44E858C82975, +459BC12982B1, +45AE5DDA9830, +45C414CDC347, +45CE4E504C06, +461744C8EABD, +46D012CA3BEC, +47170BD112B6, +47C43D5DD234, +47CD4AC26271, +47D410D1C7C4, +4808C5AD0115, +485BEEDBC293, +486001404A80, +488CCC60B70A, +49204E3CA169, +495657C78147, +4970714D53D9, +4AA715A0BBB4, +4B9901AEC16E, +4BE0B912A5A3, +4CBC34D10D83, +4CD3ACABC6A3, +4CE00134DE1E, +4CEB27151C49, +4D02A3D7CE48, +4D13683C7960, +4D1A263BA48B, +4D23919463A3, +4D9763C083D9, +4DAC8EE52C68, +4DCB89C7B2E6, +4DD9D9B637C4, +4DE6CB63A920, +4DEBA10CC85D, +4E232A8C2E30, +4E2879A411E7, +4EA7B0BED74B, +4EB8761372EA, +4EC2B23135AB, +4EC71DB088DE, +4EC9AB4B5519, +50179E461EE6, +50265ED9D468, +5047DC2975BE, +508357498162, +508BE54D326E, +510A8C52AAC4, +511335CC92CD, +518229589A81, +5184D04315D7, +51B4AE31B246, +526EDB918BEE, +529CE44BEBCC, +52A843082BB3, +52AE9A909674, +5313E9079489, +532DE5E7E0E9, +535508AA6C91, +53691569B669, +540A5B789761, +547B86E57596, +54C649075B57, +552249203848, +55430B5318E9, +5570D22DC66B, +55710879E113, +55D2E4AC0446, +56207539825A, +564664475726, +566441C5C28C, +56A7930913C3, +56C944B04618, +56D455A8BBEA, +5726991C8C28, +5726AA3BE37B, +573314090BA5, +577C31903867, +577C528E786C, +57AD9604ED24, +580C377283C7, +587329CE3EBE, +587C34557B36, +58B11E803B58, +5902E4DCC95D, +5A060A64C535, +5A36898CA7C5, +5A4740D952EC, +5A6ED7966868, +5A99578CAA13, +5AAD6814E68B, +5B065568048A, +5B6CE0B3AD0A, +5B70E0B11758, +5B926E3751EB, +5B9CA63C4267, +5BDC1391B289, +5C1D3898D537, +5C34B8E4A456, +5C36456EA1E5, +5C43A75C65A0, +5C5752328A47, +5C9D20250D74, +5CBA3CEE351A, +5CD5E98A2864, +5CE0EB9C01B6, +5D384E6A4145, +5D9DB8445155, +5DE8717BB640, +5E1A4EE98748, +5E45A227B391, +5E8E50B3048B, +5EB0EA0A9412, +6032C47B7676, +60E0C84ADDEE, +612A447A2149, +612D81821854, +616B820EAD01, +616D75A4A022, +61DE2B085AC9, +62312EC272A0, +6232C5262CC6, +62B7C7C9B0D0, +62C531C6E29C, +63E6AAAB4433, +644ABCC3DD12, +64AE7BEA1784, +6515B38077D6, +65972038CC25, +65E120DE5E55, +66141DDE8320, +66718BD91332, +668082242328, +668920AEE063, +6696C4332D46, +66C9880D1DC2, +67150CB11E95, +671737BA0054, +673551D0A99E, +676D682C4336, +678B98AA2E86, +6847808E63EE, +6887A122AA62, +6888C514DEAD, +688BD5B7B4E9, +68A99E258692, +68C312391560, +68C9D33E3735, +6900A069E3D7, +690155BE8D8E, +69174742042D, +69B9CE233517, +6A0B123D7595, +6AB8E2B49E25, +6ABD4C4A72D9, +6B1CC539A1B2, +6B30B6B0925D, +6B638C1C950D, +6BAAAB1D4589, +6BAD01EBE736, +6BB4ED5E1682, +6CA178E036DA, +6CE210B529C4, +6D23D505D2B1, +6D3CBD12BC6D, +6D83563EB521, +6D98AB9CCC71, +6E3D7366E78C, +6E5582237608, +6E6602904925, +6E77B8EB6444, +6E978A7B16C6, +6EEC05EB651C, +70284824B26C, +702CDACE0C14, +704E1B85BED8, +70BB123776D6, +70CCC3A2D7C0, +716A747CB931, +7173E199A420, +71BC9C9E31E4, +71CAEEA3B771, +71D8BA423D55, +72253C7DD951, +7260377CD286, +7280858E8B20, +72913BDAB647, +72B5B87BBC6E, +72C83B1D098A, +72DA8050A38E, +735C2AB60A97, +736B602A93D9, +738D7833E7DE, +73E7B22D6E54, +74133B1E2DED, +74A929877793, +74E3670C045A, +7531E3E2A41C, +7542A9B65EB4, +7564993C91C7, +760ED0AB626E, +762E0E021E38, +763D7E6BB40E, +764B38E2903D, +768016001C8D, +76A616C3D42C, +76AE99D9A294, +76BAAA710D25, +76E3B23696BC, +77322DD2E184, +77B40902B6D9, +77C0AC14972D, +77C1CE0E7674, +77D7B7E2C8BA, +78279397A68E, +7836593AB838, +783859EB51A6, +78CCDB50C193, +7932684154AE, +79604362370E, +796630ED27B3, +799E4E270953, +79A00573947A, +79B798D66B01, +7A0455D0A7EC, +7A33D19B7248, +7B0A8AE18817, +7B0BA045AB35, +7B0DE8504D57, +7B21781EC649, +7B7224C1AB79, +7B90C2BA9B23, +7BB90D382672, +7BBC9DC92836, +7C09DC408C47, +7C418B493454, +7C491D518242, +7C7A86CC727C, +7CE836EBD228, +7D49042C530D, +7E5744EC286C, +7E680A48C383, +7EC45CCEC35A, +7EDADA19EB57, +8005BD088847, +8022E705B640, +8031E3565825, +80499BAA5959, +807466CCBAB5, +810518578380, +810D24CB13CC, +812B02C34A64, +8163A5DDE1CD, +8186CE2B363E, +81DE6062B9D7, +822017D8929A, +8247C78188C5, +8270D538D5E8, +82D8E8DDE296, +831207CA6E8A, +83378A077357, +83A05B477535, +840160379EEE, +84044BAB78A7, +84366C6D7781, +8442CC9AA777, +8470AAD30447, +8498740493BB, +84A35A698E93, +84ABDE484425, +84B24DBB9A67, +84B723B2A237, +852BEB133D74, +854501E98239, +854A0ED2E77D, +85A066D39785, +8619557091AA, +86228C3742A4, +8637BB3BA795, +8642D9310B46, +86538085966D, +86EE9C410811, +870A042C1B34, +873B47C457E6, +873CE44DDC6B, +874D123262E7, +87513C960770, +877641436923, +878A091B74B7, +87927467808B, +88C2E39B5990, +88D252AC1A8A, +891EDA20BDEA, +89267DEE07ED, +892CB89ACCC6, +8A2423E9D100, +8A6BC2E3811B, +8A8EB5771EE9, +8A906B4B3211, +8AB21B524C5C, +8AB823BDC2AE, +8AC3B2ADE77B, +8AC4317D049B, +8ACD6B86EC44, +8AD966CA3B4D, +8B0A3B3DCDD4, +8B1B6C705C1A, +8B1C75E27153, +8B2A5E0332A1, +8B6216E412DB, +8B7CCA9DB004, +8B9999AE9703, +8BABAD9A65C6, +8C32D0AE3DB7, +8C99807368A5, +8CC1133D7D5B, +8CD2C872187A, +8D0563B86DD4, +8D43D81E37B4, +8D96A800B21A, +8D97B475C957, +8DA62EC0C524, +8DACA1BC0636, +8DE3B131D728, +8E55316D3B3D, +8EE497C9A869, +90210DDAB57D, +9026977EB8A6, +903AA4305025, +9083158A49A1, +9092D12E7967, +90D8713352D1, +911E097A27A9, +9140EC087241, +918A67D05479, +919B1D357E91, +9210BBA2AB26, +9224B6555E30, +9226D4D1236A, +922E7955CC67, +929CC86B1B26, +929E1556110E, +9302DEB79C5A, +9384841B4702, +93B4BD1CB47C, +93D985D55712, +940B37939AC6, +94673AE73823, +947A8147E0AE, +94CD6A4B6391, +94CEEAC5A8D7, +95ABD3A7C631, +95E1C233EDE2, +9607AE17AD09, +960C98566E52, +96435BD1D29B, +965D66E19245, +965D72659982, +9695167B4149, +96D0C3996714, +97274C21BD6C, +973186B345BB, +973A28C983A3, +979686C51AB6, +97992CE2DD31, +97E9D0C89DA8, +97EB8A44C49D, +98314DC363C5, +9860DC044565, +988D023C15A5, +9917BDA7B4D7, +9996A233442A, +9A2132B5B625, +9A694755A978, +9A7911ECC275, +9AA1E6CE588C, +9ABCCD2AE7C7, +9B39A60D3841, +9C0630361CC5, +9C4E19AB64B1, +9CE96BADE4D8, +9D442B28BD11, +9D4C35AE1A08, +9E02910C691A, +9E46407C9024, +9E74D104ACEA, +9EDD416A7912, +A026642D13AD, +A12908B38536, +A16EE9666D5A, +A199132A4043, +A1AEC2B58BBA, +A1BE42A15EDE, +A1D0844C2C63, +A1E0103A1879, +A253602B9445, +A2B019B46CB9, +A2BBCC3B546C, +A2C325A73A9C, +A2CB60E815A0, +A314B97C1A6A, +A3647146C335, +A3A580799BB4, +A3D30CC8EB97, +A402B5137D86, +A42158CC74B5, +A435DD64AD17, +A4693D21013B, +A479A91EED49, +A4B30D146A01, +A5142D626200, +A54056E87CBB, +A57DBD287491, +A588C918E327, +A593071D4758, +A5CC0EE7B9E3, +A6375E98A5B5, +A666347B3B4B, +A6A203994202, +A6BAE1A1520D, +A6E9885AA49D, +A705087E89A8, +A7072D4324C7, +A745AD7D6789, +A750456E7C5E, +A783A8774651, +A787C822020C, +A78BB575EAC5, +A7905680A254, +A805534D84E9, +A86C2595A1C3, +A89903B6ADDB, +A9182707A219, +A9391782A846, +A96B08E3A50B, +A98DEB0733C9, +A9C37CE71D23, +AA2D69C757D9, +AA4E4558A9EE, +AA6C835C9124, +AAC0C35C43EB, +AB30CB2CB354, +AB6191DB240A, +AB8953D3560C, +ABBB521319E6, +AC47461358D7, +AC58C25A1559, +AC7D4B201D92, +AD061A23287D, +AD105D52DB36, +AD4EA84D7185, +AD5038D15490, +AD97523144B2, +ADB24E78784B, +ADCBD453B232, +AE516A187825, +AE52116C234C, +AE817239CAB5, +AEA5A5A0E46B, +AECC93678543, +B0452769A83C, +B04D71906C60, +B0805C191424, +B09172DDBE43, +B13AE369390C, +B14080E570D1, +B1419B62772C, +B14775DEA2E2, +B188BA649EA1, +B1BB0DB95C67, +B1BB19BDD424, +B1E8B5054DAD, +B1EBB537CC0D, +B2174092CDC5, +B2554CC8AD6E, +B2C5A2E88304, +B312E56ED250, +B37B48D8C1C5, +B39C699CD208, +B3B121208E34, +B3C3C6E4395B, +B410B958C3B8, +B4204546A74E, +B45171C5A67D, +B4B103E693ED, +B4DACABCAB07, +B506567A2B84, +B51083D5C2BD, +B54D7674CB90, +B570E5EA1DA3, +B598984AD584, +B5D7E1135821, +B60D053A36D9, +B63957593E23, +B64558CAC0C9, +B68175BCA864, +B6CD1A3EC5BC, +B72468A7710D, +B75176C82A8B, +B7AA0CA5D94A, +B7B9D7E523B8, +B808D87AB75C, +B93A6432E51A, +B941A9D99B6C, +B9DA40920237, +BA6C2E10086A, +BA7384AB949E, +BA8DEEE045E8, +BADC2149EC42, +BB1924266B36, +BB41640E6340, +BBB475DB2B03, +BBD4C4699719, +BC0B2C897267, +BC7BEE6B71C4, +BC8B21AD8802, +BCA2D8118631, +BCB7A7006400, +BCBC6637499B, +BCBD2B8BE4B3, +BD213E28C568, +BD32E4EC7080, +BD401D63C3E9, +BD463C3693A4, +BD749E85586A, +BD7CA11B9551, +BD96355CBE36, +BD9E6EB7B524, +BDADE6111218, +BDB576D1E88C, +BDB5DC09C522, +BE19C75D6B7E, +BE5B3ED935AC, +BEA20C972E70, +BEEB4A159B37, +C01E8740DE38, +C0411C28857D, +C045544AD1E4, +C04660B76831, +C0C4CA21B876, +C0E0E092C8B4, +C0EE394D3D95, +C14601C6B411, +C16EBAE928B2, +C189A791A85B, +C1ACDB8C1890, +C1C55A7A99EA, +C1D72A47755A, +C1D8B91D65AA, +C1E6149B386D, +C22D8E2B1E37, +C23E999B6298, +C314E31A670D, +C3D275A9B8C7, +C3EE19B61C89, +C427B93DC2ED, +C443EEC4330D, +C477B966D328, +C4C6CAE4784C, +C55875BCB82C, +C581CA998910, +C5ABC0A455C5, +C5BE33E6B1E2, +C629E0D34581, +C65194543D6B, +C67B8E869D90, +C6BC3B9CCB41, +C7034BC581A6, +C748500B6947, +C757C15E9E0D, +C798A8465ACB, +C7B6702AC17B, +C849133B7CCC, +C870C98A4E91, +C90B7AD266D3, +C90D996C3A2D, +C953797CCE61, +C9639352EEC8, +C983685AA86B, +C9CCA6D095A3, +C9CE81D47EDB, +C9D449AD9970, +CA0D9CCC4C38, +CA277AC09859, +CA56EB045188, +CAB92B865BAD, +CAE8572C2657, +CB1CE185575C, +CB2ECC3D9C22, +CB642A081A89, +CBBAD2DA0EC5, +CC1B5BD45315, +CC2C02300D34, +CC559969D0CC, +CC5646BD7AEB, +CC6A93BD93D1, +CC726DD08765, +CCBBAB6504A4, +CCC1EA3E27B8, +CD16EAB946E9, +CDB4EEE02E14, +CDC21E1E1EC7, +CE09B3870EA2, +CE5AA0C8B5A8, +CE63DE29E069, +D0368B24CA49, +D0489010A72C, +D075379A21A6, +D09893B4EE04, +D0A7A2787570, +D0B8C06C02E4, +D106E94A4C3B, +D11E7D1BBEEA, +D12B25B8DDE2, +D1972D6CE2C3, +D1B91D224946, +D2752E53679D, +D35B2B75CC52, +D40E935117A2, +D4C37528DC05, +D4C818A5455E, +D4CD56DB8AEB, +D5190BD5CED6, +D55E5AA3406D, +D576E9D856D9, +D5E444E9D82D, +D61A3231790D, +D669B3AE1E11, +D6C075899D06, +D6C3503456C4, +D7AC70A05A0C, +D80A37B6D7ED, +D82E6938C58C, +D85E51344EB6, +D8809EB9BA7D, +D8913C2D48E9, +D9109460D912, +D94E36427E20, +D97E55B1816A, +D99425130C1A, +D99C3222A190, +D9A207103ED7, +D9C70CC5818A, +DA3379D12773, +DA705702248C, +DA818C56CE43, +DAE1888DCC0B, +DBA0A2DCA8E0, +DBD9799E15B1, +DC242193D7E3, +DCB5AC62946C, +DCB75AEC61A0, +DD6E0587A821, +DD7B1A7C6A82, +DDA22A189095, +DDDAE53AA711, +DDE7304E78B6, +DE1B4DA681B9, +DEAC67E2D7C1, +DEB7D7E4C62B, +E127434AB3B7, +E1ACC6742AB7, +E1E59574ADBC, +E1EA6BAA03D9, +E222553A59A2, +E2230B8E84C9, +E33E807EC3BA, +E341574B2E32, +E42868808B70, +E43562C624B0, +E43D54DC3511, +E466090D2123, +E47069DA0C44, +E49DD6062901, +E4ACA0ADBA0D, +E4B976AD6687, +E526BB7888DB, +E53354B71B10, +E57581CE8617, +E61A1DA5A60E, +E6293BDA5EDC, +E64C2A07CA9B, +E6600C4D6A44, +E6655B6425DC, +E6BADC631036, +E70143BE0091, +E75E07A010D1, +E76962E3B8B4, +E8028A6DCC90, +E80C5E3E8227, +E8779E40450E, +E8A9E2D87D36, +E8B5A0BDD993, +E933DA9735C4, +E93A2E63189D, +E9447637E40D, +E94836269887, +E94D82A564BA, +E98DC3B561B5, +E9EB2DE57AE9, +EA490920877D, +EA4C494C9353, +EA9B1695DD91, +EAD0E31A6834, +EB16B6462B66, +EB276C9AB68D, +EB3C9732C3BA, +EB44DDC408CE, +EB8536C958B2, +EBC825C186B3, +EC1A55BB58EB, +EC2B12107313, +EC8CB5758097, +ECD4C42EA3D1, +ED22B7115435, +ED2CE17A590C, +ED65A9B6469C, +ED6748113E0D, +ED8CEB8B7102, +EDCE0890472D, +EDD4A2EA7493, +EE17C426D25E, +EE487A4C806E, +EE5931913A8D, +EED56840AEBA, diff --git a/client/dictionaries/icbpm_sort_keys.dic b/client/dictionaries/icbpm_sort_keys.dic new file mode 100644 index 000000000..b4a635d44 --- /dev/null +++ b/client/dictionaries/icbpm_sort_keys.dic @@ -0,0 +1,1001 @@ + +00383D96411D, +005307DB7853, +009A4C4C6C49, +00C447B8A2D2, +01124119AB54, +0117BAE4D8D9, +018861488381, +0267B4922681, +02974B9786C9, +02A46AC9233A, +02BED876BD48, +02D8A7729ED3, +02EB32B92D30, +03C34821DE9A, +03D87397E9A8, +042CDEE5D0BA, +044ED79417E1, +04524659496E, +04602A40C037, +048451A79DA1, +0490AD0C9283, +04E16965C142, +05138E278443, +052B99EC186E, +056D4B5D2915, +0578E317C419, +05865124E5CA, +0599E014139E, +05DB68DB9364, +066C127C208D, +06966B31A285, +06B577E0E480, +071B57D258CE, +072B300309C9, +0759955331EE, +0769855EEC13, +079B8DA54DB1, +082B68A67491, +0832E4783600, +08506533E741, +0853A982D793, +08629D1DD0D6, +087C0CDA3B46, +08AE4ECD7CE3, +0965220D2ECE, +09A14A80754E, +09ACEA48DD0D, +09DB8EE5458C, +09E6CB76C080, +0A44A754B592, +0A7328887DC2, +0A906663EE1C, +0AB08938E3DA, +0AD8AD0739A6, +0B00220EAE75, +0B1960681E79, +0B31815E6A7C, +0B3690D4B122, +0BB8414CB6EA, +0BEC525E3463, +0C296648344D, +0CB6CC83AC45, +0CCAD03DDBC6, +0D6C26AB25CD, +0DC9143735D1, +0DE8A36CBBCC, +0E175033BD77, +0E6478123917, +0E7D4AC83133, +0E8420B04083, +0EA607E1C4E3, +105743704432, +107A6AB6B305, +110BB6D5539D, +1114A47CC39A, +116AA873ACC8, +120616C6208E, +120C83C06317, +12343D71106C, +123A082E2AEA, +12E50BE60524, +133DC845505E, +138153A4351A, +1395C108B6B6, +1428C04BAAD1, +147D93848C70, +14A353C60820, +1504C1846399, +1523A1E39D03, +1532A2511A8B, +157308368E8E, +16065CC411E0, +1637D8ACA71E, +1639134699C7, +167358BB268E, +168DE72B3B5A, +16A05D5C31C3, +16B4442EAE97, +17197B247A4A, +1774DB1A8CA1, +17820DAA47B2, +1782BEDBD347, +17B561AA82B4, +17C548CBC3A6, +17DA5C873BC5, +18025130661E, +184B95B4E3C6, +18A3196D364B, +18A97BD26818, +18BE810A83DD, +18C3AC2A7E90, +194D4E1DE89D, +196E279BE9A9, +1A2C8D855336, +1A3A76ED470A, +1A55D4849951, +1A9872D00EC9, +1ACD5433BBDD, +1ADC527D5BDA, +1AE29C8CD672, +1B14CAC3D0C2, +1B20A6E1D06B, +1B30A7825B23, +1B3E45AEE657, +1B75E7B007DB, +1B9DABDEBAE0, +1BAB19D01495, +1BD3119E0363, +1BDA0D87A575, +1CD38D77090B, +1D12BBB575B1, +1E1A0DB8729C, +1E2DE60A477A, +1E3C71643766, +1E6ED46CE258, +1EE60A4A8D22, +200D45263629, +2013899194BB, +206CE78E0C6C, +20B51C977E54, +2142B57D369D, +2172D827D3E2, +2178ED80D581, +21B4BE97AE07, +21B91A26133A, +21C7650673CD, +220D815D366A, +22C2176E1CD6, +22C3AB41B123, +233D7B324CEE, +2340CBD61A71, +2348251AD23E, +2381B8214025, +23BAE8DA1AC5, +23C317B8D6DA, +243A41574A39, +248EA5E91987, +2491457885A7, +255A9E590BCC, +257192699E32, +25892216C620, +2595E5B1DE76, +25AE69DED1B4, +25BA8775B3C4, +25D967D4DD35, +25DB996D56ED, +25EE21CDE4B9, +2625E408276B, +26B744C673DB, +26C6D38B8257, +26D787613684, +27689527E201, +27743B5A5736, +27D1635ED1B3, +27D5B8D2642E, +28035CA5B300, +2812EB6A427C, +28133B46730A, +281499DD16A0, +281DD9E6C98E, +2870E08CEDBA, +28B8685B1B22, +28C3D17E4DEC, +2953C63E9E58, +295D3C9A8B28, +297B74853CAA, +29ACACC2828E, +29EA97BC4A6B, +29EB3CA1C0DE, +2A079CC2AD37, +2A27E0602400, +2A45A0D8D6EE, +2A47CDD3A322, +2A4C4DB1D71D, +2AA82B4B6711, +2ABD68BDC5A3, +2AE7BDB10CB4, +2B051C90BE82, +2B490231E063, +2BAB94372644, +2C03252C10E7, +2C3EE5E98804, +2CB671E6365D, +2CC55B46705B, +2CD09D3C0A1B, +2CECBC323E31, +2D302827C9B4, +2D716C9C467B, +2D8856109732, +2E15681A4355, +2E79209B9519, +2EEE063290C1, +301C9AA3DECA, +30C520D6A2B9, +30D6324910AB, +3113AADC9D6B, +3124ACA5491C, +315AD0D6E6D2, +31A16DAC864D, +31EC44581294, +32DE3CD81C24, +32E532232C29, +33256E443128, +33293485AD61, +33305B0365AA, +3343B72BAA71, +3372C9C5D4AE, +33754E0D1687, +33A444334869, +33B54345C32E, +34002AAEE45D, +343C556CEE59, +3444DDE6D7E5, +345B62452538, +3495A04A9270, +34EB673C863B, +35123500C1EA, +353A7167576B, +3599856810B2, +35E7DE9899EE, +35EDABB506D8, +36C54912D10E, +36CA0101B6DC, +36D268442846, +373E5827E0B8, +376D6C446746, +37E2EAE635B5, +381B0A70E135, +3862B259DC71, +386676C44A13, +3905679DEEC4, +39070618BB17, +394181105544, +395D38815892, +39A00E856381, +39C0E2ED99B5, +3A1E82E2CDB7, +3A5D13E05B6A, +3A6DE2081CDD, +3A8498924010, +3A9D49E8BEB2, +3AD0EE1031A9, +3B052E65D40A, +3B4986981212, +3B4C51ACC53D, +3B99486097C6, +3BB36BC22CE4, +3BB4B3025B79, +3BBB7BD8D7B7, +3C09C971D835, +3C4A12E7A107, +3C633B3474DD, +3CB9E31D6022, +3CD344A7EB21, +3CD8C6705954, +3CE887B9D091, +3D5EA1C71953, +3D89120EB993, +3D9C3245AE76, +3DED9D496478, +3E0913A96E74, +3E34909990B5, +3E7DD7953DDD, +3EEB33434C1A, +4015D16B5C1C, +401C81A72C56, +40E7B8D60242, +41016C0CB8DE, +4124864B0D40, +415BAA0CAB15, +418184DBB4A0, +419513740558, +4195EE7238CC, +41B727883B27, +41BC44A8C3C6, +41DDC3A48EEA, +420445087613, +42068108DE36, +4245921D73CA, +42A959953C45, +430E67734C18, +4314D9D03B95, +43166BCA83EB, +43400A093A7E, +434CE764DE91, +43595AC786EE, +438099331C1E, +43814087A7B5, +438C3CD95B58, +43B3E895B281, +44074C461042, +444D37149B20, +44A04DAA30CB, +4537282554C5, +4584EACB6087, +45DB3799C150, +45E599AE38EA, +462305611C4A, +4636195CDA2D, +46752993E2E9, +4684316440D6, +46C7246C1958, +4751A5274848, +4761E34CB054, +476388408D8E, +478947735B45, +47AD81972D5B, +47C23398EA52, +47E9D4D4BE35, +4812AEC4B01A, +48276645A4EA, +48644467A214, +489C783B3514, +48C860AA4B74, +495C6639575B, +49681C20A00D, +49E8249DD677, +49E93C110AA1, +4A24470C19C5, +4A4755BC4A2A, +4A4D5E3A9011, +4A65D627625C, +4A6B36C5BCCC, +4AB725ED89B5, +4B39E3923D0D, +4B59316C10E0, +4C275C8BB2DA, +4C2E9455D296, +4C44DB1D0C3A, +4C67059B0006, +4CA30E1A298A, +4CA74DAC7C01, +4CB212D72D57, +4CD3B228EBB4, +4CE1972E090C, +4CEE1794E0EA, +4D06DBCA167E, +4D2CC85EB338, +4D40BC7A44DB, +4D769DA515D3, +4D79C95DAD2D, +4DBAC8ECE167, +4E3CB839E87D, +4E3D548E1267, +4E8250E29617, +4E94C7962769, +5038884E4178, +505B5A8EB20A, +50642C36DA00, +5083664D8C09, +50B77DA96DE2, +511E269A9BAE, +51798AEAAE9E, +51ED5833AB6D, +525335E4CD34, +5261CDDA279E, +526E55542A54, +529C16A720AB, +52A230B1C50E, +52AADA374811, +52D20D6E3E35, +534BB4A6984E, +5352CCC3DCD2, +540B15E8019D, +54AA2915E815, +558DB8891A90, +55A691710B48, +55D1E91B1D35, +55D95774E9A0, +563C6B96D59D, +567032E13B54, +56741B108D22, +57029D991123, +5714E9D33034, +5734CD8A65DA, +5785EE00049E, +57B8B111491D, +57CC9D0AA32B, +57D7D4D746DA, +583C936DCB4B, +586B470A43B3, +5876E1D34183, +58B6AE62DB88, +58C35C8BC9AB, +597E98000ED4, +59DB4DBB5D7A, +5A150653E624, +5A211CE57C4B, +5A6272CDBE9C, +5ACB8043C10C, +5B41CEBC2213, +5B59BCC4321E, +5BA03479BB8C, +5BC64C42281C, +5C9B1A8E31CD, +5C9BD0AC1DB1, +5D223E990AD8, +5D8C3A5C5761, +5DA57EACA38C, +5E41DD5D1154, +5E6ABB51EC75, +5E7CC04C3A58, +5E810C48C8D8, +5E8943D9A836, +5ED616273468, +60100DD0E023, +6033A1C0E431, +6088A566CC60, +60B20ADA0471, +60B8411D876E, +60C742D8D9C0, +6135433CC5EA, +6153ADD80A15, +61718ED2C94D, +6175241B035A, +61780BCB0C57, +61B701698050, +61C4E56629A3, +61D59C284952, +61E57B490A55, +622E5E0812D7, +6251CE7E547A, +62953A89B137, +62D6EAA06CD6, +630228659A47, +632931BE8EC7, +63539BB89DEE, +636CB69BB10C, +63783393E20D, +639DB16995B7, +63AA2A5B076C, +63B636458E94, +6443E64DCC4B, +64695084C575, +6493D06D5710, +649B302A97C5, +64B8632B54D4, +654BACB21C3B, +65A3D5823819, +65DEDABD1B34, +6608944EE186, +665B8B24C20D, +6685D0BE19E0, +66933A9E7982, +674C7BB59A16, +675E35EE359E, +67AA98E362C9, +67D47C1B6425, +67DE22850162, +67E8B986B2A7, +681EA28BA6CD, +6828B52B6507, +6874E54471E8, +6879B1CA44A3, +68C00A810D41, +68C9E8AA5C3E, +697A8ED07418, +69B5357A617A, +6A7B3A7B6735, +6AA40421D23C, +6AB676B4DB9D, +6B00420BE41C, +6B0B7B967871, +6B9D041136B4, +6BB1A14768A8, +6BCAE24D9700, +6C0458728774, +6C57CBD51995, +6C5E10B86CDE, +6CA491A8C7B8, +6CBC25C1DA2E, +6CD430D99958, +6CEC27647CC0, +6D4D29CEB9B5, +6D6E9A6B725D, +6D801AC74572, +6D97408C6D60, +6DDE6E871C64, +6DEA848B6195, +6E05B5C44A54, +6E751666AE9A, +6E7DBCDA05B3, +7004BA1763ED, +7016ECD01559, +7076D48D5E49, +7091621EA016, +709311997549, +70984C14D3DB, +70D73BE22CDD, +70D9461C5E90, +712BC18422CB, +712E6CAA74A4, +7164042BA89E, +7175E14A4D62, +718B39561350, +718BDA352E28, +719B1418323E, +71A8D54D82B3, +71DC30168C27, +7221E016597B, +7234CC6BD65D, +727A80DD5296, +72B393D6E8A9, +732C9BE4DDBA, +736B4A835B2B, +73EA81968900, +740AB5126199, +741A31054E6B, +74498C1D4B3D, +745276053CB6, +74684B0B4B1D, +74772915E24C, +74A24BE33BE2, +74A778236D5A, +74AA58008A31, +74C27A96CB3A, +754AD5773746, +756C15E54212, +759403A563D8, +759D2130312B, +75A0E10D8C84, +75A807E46B96, +75E454785C6C, +76078A25C088, +76140285B768, +763D835BD5ED, +767C33468C72, +76962C07EC9E, +76984E62CCE4, +769AE4646931, +76E5DA67A1EC, +7708D5CAD58B, +77383BAA4D90, +7789E646A556, +779A248E098C, +77DB71037644, +77E0A57DD456, +7853D464E2A4, +78EA6EB04463, +7909427EC8B9, +7910A31ECD19, +79271963B6E8, +793D98517D33, +79B7A4C58DE0, +79B9148761B3, +7A2893B75AD1, +7A4C61A1B48D, +7A7469B69C6A, +7AA84B1A527D, +7B00211CA416, +7B118EABC7BB, +7B1D9A2E22AA, +7B583D350740, +7B9D3A6BD061, +7C2DAC2CC775, +7C4CBBD2DDE1, +7CD52B5B8E77, +7D412100532B, +7D46C149DAD9, +7D4CA630E229, +7DAC0E83D335, +7DC935E220A0, +7DCA66BACA13, +7E30778792D2, +7E43C3BAB3CB, +7E475BA186E6, +7EE2A624851A, +80CED5362B2C, +80D2CC78E10B, +80D62251E20C, +816875D55ED1, +81950D0517AC, +81B519418C3E, +8211571B9D16, +823C7CC6E06A, +826DD63B9032, +827303C574B5, +82C5ADED4B81, +82E344329D34, +83588E140165, +835D33B48113, +8384148AE52D, +8394B57153D6, +83A0184757C0, +83D86835B48B, +8502EE9A7E85, +852C2B72659D, +8534A6CE0911, +85ABD94CD7A9, +85DA8099CD7E, +85E0B6B26945, +864CA2A6BE93, +868A33A44447, +86EDEABCC357, +87DDD5A188EE, +8830379B50B7, +883803A3360C, +883DA78EC87D, +88482A12C2C6, +888EBD3DB945, +88D026793359, +88DD4B7C5991, +8931DC3733D4, +894D8E2DCDEE, +897B845C2680, +89B638BD909E, +89D2C28BE578, +8A1869848D1A, +8A39D09508C9, +8ACCC7290C8C, +8AD8B41EC218, +8B028B7E6D60, +8B6A95C7D2E2, +8BA1226EBA21, +8BD586B21ABC, +8C0EA504B635, +8CA939DC6DE4, +8CAE5D688443, +8CEC639E64DC, +8DECE0DD29DE, +8E0EC762E883, +8E958D8B8C52, +8EB64D710C88, +8ED4A17717D9, +8EE9D9C03A0D, +9014E1430AEB, +90965DEBC8B9, +90E56E616DDD, +912CD8E04437, +912E33563E1B, +918048032247, +919402EC39CB, +91D28E2B126D, +9216EEE5B677, +9232215296B2, +925A070E9096, +925A5521D48D, +92CC200886A2, +932035869655, +937144459949, +93B260DBC70A, +94552B863E37, +95327A0A3600, +954275CDD7E0, +957E6EE3EB55, +95B920CACC84, +96382E1C8E12, +964E8E5338BD, +96706C8D6ECC, +96759A0D5566, +96D5213C5DDB, +97300764797A, +973BDDBE7434, +974838AE17A0, +9752A6B316D5, +97926543783B, +97EB373096CA, +982D6054B83D, +989D127BD496, +98A54AD58A43, +98A92128364C, +98CD5AA2A4DB, +98E8C543688E, +99207A00AA4A, +99243E754CB8, +9925893ABAC7, +9937553A965E, +9976E6ADE0C9, +9982E3E6A4A0, +9984C1A3229E, +99C487AB85EC, +99E2A19C9673, +9A05EBE41D7D, +9A138D1A5CB7, +9A179148B824, +9A6EC0A9ECB8, +9A720CBD7BB1, +9AB22BBDDD87, +9AC43B5A06D8, +9AD8150BE648, +9AD97423190D, +9B4ADDDEB749, +9B7603341727, +9C45237377BE, +9D090AE1A15E, +9D59641E40A5, +9DA4528CEB8C, +9DA728164176, +9DAC62A346B7, +9E0E9D983B9A, +9E5271763D3D, +9EE95586D024, +9EEE39E00CBB, +A04671256EE2, +A091485B4B5D, +A1B5577ED36E, +A1EB280E3901, +A2789E1DD888, +A293A90AE72C, +A309E3AEBDB9, +A3196E77B072, +A31E72DCC826, +A34DEA01690E, +A36031D6ECB2, +A38044A3E18E, +A421D7A04C4B, +A424C686CA39, +A44590A779A5, +A47AD3895C63, +A5041E8B8E22, +A50DC0830AA5, +A52B8929D665, +A5BCBA6BE592, +A61D5137E6B3, +A6344C0418DC, +A690A817B9D9, +A7E3B3459240, +A81E6D3C8E11, +A8C0BE436685, +A8DE205120A8, +A91E2BE6C308, +A9258D6B06B5, +A992B5E070C1, +AAC6E3205D48, +AB101546634E, +AB6EE0761ACA, +AB9BCA200547, +AC4BC5B2D3C0, +AC7A0B47B03E, +AC88B26AC1D0, +ACAEB3456AD9, +ACB906631D8A, +ACE07B45C0C5, +AD1992AE37CA, +AD5586744A60, +AD674E4ADB79, +ADA093B06831, +AE7C3AE5334A, +AE9EB8CAB2C3, +AEAE9E5CE65D, +B002D1BDC29B, +B0463E703098, +B063B209BB20, +B0788BE3BAA4, +B0C3B3299090, +B128298D9073, +B160677E7035, +B19D3D57176A, +B1CCDB7999B9, +B231AA398B90, +B250E9590215, +B28BE0D819ED, +B292C9554CBA, +B2D8485C2460, +B31763D9D0DE, +B328014DDD6A, +B378C424C9E2, +B3D8C03C78E0, +B41D18E3B980, +B46824B972E9, +B50383A32302, +B509D631967C, +B56CA847A7C3, +B56EC9A20D28, +B5B763215C82, +B6550EAC573A, +B66060201705, +B6614EBEAAA2, +B6A18CBD4DA6, +B6ABB62E437E, +B6C6558E58CA, +B7009204D512, +B71D5B22B1C2, +B7392DD1E497, +B7709ED7CE60, +B7A26320A491, +B7A9DA22E9C6, +B7DEC863369D, +B7E9A91174CB, +B8178A34E2DC, +B83092098A7D, +B84C50E56DEC, +B89BD135E935, +B8E87380D361, +B9485A9648C6, +B9ED829C22AE, +BA227EE91818, +BA7BBD9683B1, +BA8224EA7A80, +BA84C974B356, +BAD293A45C8A, +BB850C7E4934, +BBC1256810A4, +BC1CD369549E, +BC5C76E5909C, +BC66E9270049, +BC6AB08B03CC, +BC74CA2C2B06, +BC7C64828C1D, +BCCC3A719013, +BD06E96EB7D7, +BD196D0A74E0, +BE02790E84AC, +BE1266314B9D, +BE518C742B74, +BE5695316117, +BE5D8EBA120D, +BE8286DA7D12, +BE9CE00EE4DD, +C003962B3462, +C0067E095049, +C015A21E0146, +C03BC03AD437, +C06CE7D57A0D, +C07EE1E10B56, +C0885A29251E, +C198163ABECE, +C1EB7337A035, +C225479C7064, +C2740E1665A8, +C27924128A00, +C2A701656B8B, +C2C30D21C53E, +C2CBB2ACD38D, +C38D19A9C8D1, +C3B1BB7E7492, +C3BA2438A981, +C3CD74758DE2, +C4033B3BB1D7, +C404D280640E, +C4467DE80B2D, +C46A048C88DD, +C52877867C05, +C56D005E258E, +C56D052D5533, +C5BB2CCCB9C3, +C5C272694A1E, +C6121BC4A29C, +C65EEAE02433, +C661C4AE1DD1, +C76C94B495CA, +C7BD49777A79, +C7CD131E9B60, +C7E35D6294BA, +C8E173DB04CC, +C95855AE08E8, +C98147E69033, +C99A004E6133, +C9E893C4090B, +CA119C79A197, +CA309D2CBC41, +CA4BAA390BC4, +CA92DD257E21, +CA968EBEB9C7, +CADED0C50AC4, +CB18774EA550, +CB1999D19E10, +CB75C1BAE669, +CC2517AB2346, +CC2AC1AD29CA, +CD11359C7A90, +CD14C8553CB9, +CD333295BBE2, +CD3DB8C27E5C, +CDA811AD5055, +CDABDCA23986, +CDCA8BD7B002, +CE0456AB0DCE, +CE58AE1C51E9, +CE76E8A600DC, +CE95875316C8, +CEB105E65289, +CEB651752D4C, +CEE02D97E5BD, +D023DB35ED05, +D0BE546CC06B, +D0CE7EB0D379, +D10329D366C8, +D15C004DBC8D, +D16E6B668254, +D1CEEC977644, +D1DC0E1CC09E, +D2550925679B, +D28B2D42DE1A, +D2926519AC09, +D313116A45B4, +D3DC10453857, +D431C8C73BDC, +D4C67846791C, +D5629384CE7D, +D5ABE7180600, +D62A4A0E57C2, +D660CE9E3080, +D66AE9282140, +D6A91C14AC47, +D6E23B4E75C6, +D726C4979654, +D76DE12943B4, +D7A405AD9E4E, +D7BD3AE48E93, +D7D49700BBCC, +D7E8A5089E7A, +D84C81EE910D, +D8545199A949, +D86243C1380E, +D88A12EB3622, +D89B5EA419C1, +D8A3690B0115, +D94646A4C65B, +D982B4846A96, +DA303BADB013, +DAD9A48A8C33, +DAEB5D63920B, +DB01A99DD94C, +DB22BB7D6818, +DB37160CBB4B, +DB7E3687E450, +DC7697E37A9B, +DCC44C4E9269, +DCCE477E785E, +DD68DE9CDA5A, +DE1B08C6D94B, +DE41BBD7E68D, +DE6E04AE4475, +DE8CD4277A9E, +DEA8098D6E51, +DEB2BEE8858A, +DEB550958AD9, +E045E6309471, +E0E21213C611, +E0E457054B62, +E1097C69DA4A, +E1EA831EA514, +E20716902884, +E2C9CB14C06C, +E33B66EA2705, +E34C5B12BABA, +E38A1C654E82, +E3905BA54194, +E3E3919444CA, +E4450EC1010C, +E49A03306224, +E5100AC4C6C3, +E5124DB665A6, +E5491B5E3DD6, +E5BE9C989A29, +E5C3A9A27D3E, +E65111EB1E40, +E65792427D4C, +E7004C5EA94A, +E705087DECBB, +E7CB93E68155, +E81512343BAD, +E8428C8B0740, +E859EBC22318, +E87267A508DB, +E886AE7D1BE0, +E8B008239600, +E8C4B4A4E482, +E8D53410B736, +E902964DA28D, +E9203D5BD2DA, +E9526CACA8B2, +E9C11D763BEC, +EA3BDAA4E498, +EA61AC8B4969, +EA8E8ADC26B9, +EB5588EAE5E8, +EBA964C07075, +EC71B679D3AA, +ECB4019ADD97, +ED14D0A14B0C, +ED296C79266C, +EDBA3C943EA8, +EDC7CEBD4000, +EDE2747DA6C3, +EE3029556CEB, +EE49610E6121, +EEB704D69BCA, +EED69A391464, diff --git a/client/dictionaries/mrzd_sort_keys.dic b/client/dictionaries/mrzd_sort_keys.dic new file mode 100644 index 000000000..025f1b995 --- /dev/null +++ b/client/dictionaries/mrzd_sort_keys.dic @@ -0,0 +1,57 @@ +010203040506, +013940233313, +022FE48B3072, +123456789ABC, +123456ABCDEF, +17505586EF02, +1795902DBAF9, +1A2B3C4D5E6F, +1A982C7E459A, +200306202033, +2011092119F1, +2012053082AD, +37D4DCA92451, +40E5EA1EFC00, +435330666666, +46868F6D5677, +474249437569, +4D3A99C351DD, +533CB6C723F6, +5554AAA96321, +587EE5F9350F, +5A1B85FCE20A, +5D293AFC8D7E, +64A2EE93B12B, +64E2283FCF5E, +714C5C886E97, +833FBD3CFE51, +83BAB5ACAD62, +872B71F9D15A, +8F9B229047AC, +8FD0A4F256E9, +9AEDF9931EC1, +9B1DD7C030A1, +A0478CC39091, +A0A1A2A3A4A5, +A2B2C9D187FB, +A4EF6C3BB692, +AABBCC660429, +AABBCCDDEEFF, +ABCDEF123456, +B0699AD03D17, +B0B1B2B3B4B5, +BA28CFD15EE8, +BCFE01BCFE01, +C0C1C2C3C4C5, +CFC738403AB0, +D0D1D2D3D4D5, +D3F7D3F7D3F7, +DB5181C92CBE, +DFED39FFBB76, +E1DD284379D4, +E96246531342, +ED3A7EFBFF56, +F83466888612, +F89C86B2A961, +FFFFAE82366C, +FFFFD06F83E3, diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index 71cf542db..d0015ac38 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -623,7 +623,7 @@ int CmdEMVInternalAuthenticate(const char *cmd) { return 0; } -#define dreturn(n) {free(pdol_data_tlv);tlvdb_free(tlvSelect);tlvdb_free(tlvRoot);DropField();return n;} +#define dreturn(n) {free(pdol_data_tlv); tlvdb_free(tlvSelect); tlvdb_free(tlvRoot); DropFieldEx( channel ); return n;} void InitTransactionParameters(struct tlvdb *tlvRoot, bool paramLoadJSON, enum TransactionType TrType, bool GenACGPO) { @@ -1244,7 +1244,7 @@ int CmdEMVExec(const char *cmd) { } - DropField(); + DropFieldEx( channel ); // Destroy TLV's free(pdol_data_tlv); @@ -1346,7 +1346,7 @@ int CmdEMVScan(const char *cmd) { } // drop field at start - DropField(); + DropFieldEx( channel ); // iso 14443 select PrintAndLogEx(NORMAL, "--> GET UID, ATS."); @@ -1399,7 +1399,7 @@ int CmdEMVScan(const char *cmd) { if (EMVSearch(channel, false, true, decodeTLV, tlvSelect)) { PrintAndLogEx(ERR, "Can't found any of EMV AID. Exit..."); tlvdb_free(tlvSelect); - DropField(); + DropFieldEx( channel ); return 3; } @@ -1415,7 +1415,7 @@ int CmdEMVScan(const char *cmd) { if (!AIDlen) { PrintAndLogEx(INFO, "Can't select AID. EMV AID not found. Exit..."); - DropField(); + DropFieldEx( channel ); return 4; } @@ -1434,7 +1434,7 @@ int CmdEMVScan(const char *cmd) { if (res) { PrintAndLogEx(ERR, "Can't select AID (%d). Exit...", res); tlvdb_free(tlvRoot); - DropField(); + DropFieldEx( channel ); return 5; } @@ -1462,7 +1462,7 @@ int CmdEMVScan(const char *cmd) { if (!pdol_data_tlv){ PrintAndLogEx(ERR, "Can't create PDOL TLV."); tlvdb_free(tlvRoot); - DropField(); + DropFieldEx( channel ); return 6; } @@ -1471,7 +1471,7 @@ int CmdEMVScan(const char *cmd) { if (!pdol_data_tlv_data) { PrintAndLogEx(ERR, "Can't create PDOL data."); tlvdb_free(tlvRoot); - DropField(); + DropFieldEx( channel ); return 6; } PrintAndLogEx(INFO, "PDOL data[%d]: %s", pdol_data_tlv_data_len, sprint_hex(pdol_data_tlv_data, pdol_data_tlv_data_len)); @@ -1485,7 +1485,7 @@ int CmdEMVScan(const char *cmd) { if (res) { PrintAndLogEx(ERR, "GPO error(%d): %4x. Exit...", res, sw); tlvdb_free(tlvRoot); - DropField(); + DropFieldEx( channel ); return 7; } ProcessGPOResponseFormat1(tlvRoot, buf, len, decodeTLV); @@ -1577,8 +1577,7 @@ int CmdEMVScan(const char *cmd) { // free tlv object tlvdb_free(tlvRoot); - // DropField - DropField(); + DropFieldEx( channel ); res = json_dump_file(root, fname, JSON_INDENT(2)); if (res) { @@ -1631,6 +1630,14 @@ int CmdEMVRoca(const char *cmd) { if (arg_get_lit(2)) channel = ECC_CONTACT; PrintChannel(channel); + +#ifndef WITH_SMARTCARD + // not compiled with smartcard functionality, we need to exit + if ( channel == ECC_CONTACT ) { + PrintAndLogEx(WARNING, "PM3 Client is not compiled with support for SMARTCARD. Exiting."); + return 0; + } +#endif // select card uint8_t psenum = (channel == ECC_CONTACT) ? 1 : 2; @@ -1654,7 +1661,7 @@ int CmdEMVRoca(const char *cmd) { if (EMVSearch(channel, false, true, false, tlvSelect)) { PrintAndLogEx(ERR, "Can't found any of EMV AID. Exit..."); tlvdb_free(tlvSelect); - DropField(); + DropFieldEx( channel ); return 3; } @@ -1670,7 +1677,7 @@ int CmdEMVRoca(const char *cmd) { if (!AIDlen) { PrintAndLogEx(INFO, "Can't select AID. EMV AID not found. Exit..."); - DropField(); + DropFieldEx( channel ); return 4; } @@ -1685,7 +1692,7 @@ int CmdEMVRoca(const char *cmd) { if (res) { PrintAndLogEx(ERR, "Can't select AID (%d). Exit...", res); tlvdb_free(tlvRoot); - DropField(); + DropFieldEx( channel ); return 5; } @@ -1697,7 +1704,7 @@ int CmdEMVRoca(const char *cmd) { if (!pdol_data_tlv){ PrintAndLogEx(ERR, "Can't create PDOL TLV."); tlvdb_free(tlvRoot); - DropField(); + DropFieldEx( channel ); return 6; } @@ -1706,7 +1713,7 @@ int CmdEMVRoca(const char *cmd) { if (!pdol_data_tlv_data) { PrintAndLogEx(ERR, "Can't create PDOL data."); tlvdb_free(tlvRoot); - DropField(); + DropFieldEx( channel ); return 6; } PrintAndLogEx(INFO, "PDOL data[%d]: %s", pdol_data_tlv_data_len, sprint_hex(pdol_data_tlv_data, pdol_data_tlv_data_len)); @@ -1720,7 +1727,7 @@ int CmdEMVRoca(const char *cmd) { if (res) { PrintAndLogEx(ERR, "GPO error(%d): %4x. Exit...", res, sw); tlvdb_free(tlvRoot); - DropField(); + DropFieldEx( channel ); return 7; } ProcessGPOResponseFormat1(tlvRoot, buf, len, false); @@ -1818,10 +1825,7 @@ out: // free tlv object tlvdb_free(tlvRoot); - if ( channel == ECC_CONTACTLESS) - DropField(); - - + DropFieldEx( channel ); return 0; } diff --git a/client/emv/emvcore.c b/client/emv/emvcore.c index 023035a7d..6ccee471c 100644 --- a/client/emv/emvcore.c +++ b/client/emv/emvcore.c @@ -241,7 +241,7 @@ int EMVExchangeEx(EMVCommandChannel channel, bool ActivateField, bool LeaveField int res = 0; if (ActivateField) { - DropField(); + DropFieldEx( channel ); msleep(50); } @@ -262,8 +262,12 @@ int EMVExchangeEx(EMVCommandChannel channel, bool ActivateField, bool LeaveField } break; case ECC_CONTACT: +#ifdef WITH_SMARTCARD //int ExchangeAPDUSC(uint8_t *datain, int datainlen, bool activateCard, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen); res = ExchangeAPDUSC(data, (IncludeLe?6:5) + apdu.Lc, ActivateField, LeaveFieldON, Result, (int)MaxResultLen, (int *)ResultLen); +#else + res = 1; +#endif if (res) { return res; } @@ -480,7 +484,7 @@ int EMVSearchPSE(EMVCommandChannel channel, bool ActivateField, bool LeaveFieldO } if(!LeaveFieldON) - DropField(); + DropFieldEx( channel ); return res; } diff --git a/client/fido/additional_ca.c b/client/fido/additional_ca.c index f529e99b5..564eda2ae 100644 --- a/client/fido/additional_ca.c +++ b/client/fido/additional_ca.c @@ -58,6 +58,23 @@ "U9psmyPzK+Vsgw2jeRQ5JlKDyqE0hebfC1tvFu0CCrJFcw==\r\n" \ "-----END CERTIFICATE-----\r\n" +// Name: SoloKey U2F Root CA Serial 14143382635911888524 (0xc44763928ff4be8c) +// Issued: 2018-11-11 +#define SOLOKEY_CA \ +"-----BEGIN CERTIFICATE-----\r\n" \ +"MIIB9DCCAZoCCQDER2OSj/S+jDAKBggqhkjOPQQDAjCBgDELMAkGA1UEBhMCVVMx\r\n" \ +"ETAPBgNVBAgMCE1hcnlsYW5kMRIwEAYDVQQKDAlTb2xvIEtleXMxEDAOBgNVBAsM\r\n" \ +"B1Jvb3QgQ0ExFTATBgNVBAMMDHNvbG9rZXlzLmNvbTEhMB8GCSqGSIb3DQEJARYS\r\n" \ +"aGVsbG9Ac29sb2tleXMuY29tMCAXDTE4MTExMTEyNTE0MloYDzIwNjgxMDI5MTI1\r\n" \ +"MTQyWjCBgDELMAkGA1UEBhMCVVMxETAPBgNVBAgMCE1hcnlsYW5kMRIwEAYDVQQK\r\n" \ +"DAlTb2xvIEtleXMxEDAOBgNVBAsMB1Jvb3QgQ0ExFTATBgNVBAMMDHNvbG9rZXlz\r\n" \ +"LmNvbTEhMB8GCSqGSIb3DQEJARYSaGVsbG9Ac29sb2tleXMuY29tMFkwEwYHKoZI\r\n" \ +"zj0CAQYIKoZIzj0DAQcDQgAEWHAN0CCJVZdMs0oktZ5m93uxmB1iyq8ELRLtqVFL\r\n" \ +"SOiHQEab56qRTB/QzrpGAY++Y2mw+vRuQMNhBiU0KzwjBjAKBggqhkjOPQQDAgNI\r\n" \ +"ADBFAiEAz9SlrAXIlEu87vra54rICPs+4b0qhp3PdzcTg7rvnP0CIGjxzlteQQx+\r\n" \ +"jQGd7rwSZuE5RWUPVygYhUstQO9zNUOs\r\n" \ +"-----END CERTIFICATE-----\r\n" + /* Concatenation of all additional CA certificates in PEM format if available */ -const char additional_ca_pem[] = GLOBALSIGN_CA YUBICO_CA; +const char additional_ca_pem[] = GLOBALSIGN_CA YUBICO_CA SOLOKEY_CA; const size_t additional_ca_pem_len = sizeof(additional_ca_pem); diff --git a/client/fido/fidocore.c b/client/fido/fidocore.c index ee39fbbe9..f83e64944 100644 --- a/client/fido/fidocore.c +++ b/client/fido/fidocore.c @@ -250,9 +250,9 @@ int FIDOCheckDERAndGetKey(uint8_t *der, size_t derLen, bool verbose, uint8_t *pu uint32_t verifyflags = 0; res = mbedtls_x509_crt_verify(&cert, &cacert, NULL, NULL, &verifyflags, NULL, NULL); if (res) { - PrintAndLog("ERROR: DER verify returned 0x%x - %s", (res<0)?-res:res, ecdsa_get_error(res)); + PrintAndLog("ERROR: DER verify returned 0x%x - %s\n", (res<0)?-res:res, ecdsa_get_error(res)); } else { - PrintAndLog("Certificate OK."); + PrintAndLog("Certificate OK.\n"); } if (verbose) { diff --git a/client/flash.c b/client/flash.c index de6fdf7e6..2c06311c3 100644 --- a/client/flash.c +++ b/client/flash.c @@ -38,7 +38,7 @@ static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs, flash_seg_t *seg; uint32_t last_end = 0; - ctx->segments = malloc(sizeof(flash_seg_t) * num_phdrs); + ctx->segments = calloc(sizeof(flash_seg_t) * num_phdrs, sizeof(uint8_t)); if (!ctx->segments) { fprintf(stderr, "Out of memory\n"); return -1; @@ -88,7 +88,7 @@ static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs, uint8_t *data; // make extra space if we need to move the data forward - data = malloc(filesz + BLOCK_SIZE); + data = calloc(filesz + BLOCK_SIZE, sizeof(uint8_t)); if (!data) { fprintf(stderr, "Error: Out of memory\n"); return -1; @@ -111,7 +111,7 @@ static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs, uint32_t new_length = this_end - prev_seg->start; uint32_t this_offset = paddr - prev_seg->start; uint32_t hole = this_offset - prev_seg->length; - uint8_t *new_data = malloc(new_length); + uint8_t *new_data = calloc(new_length, sizeof(uint8_t)); if (!new_data) { fprintf(stderr, "Error: Out of memory\n"); free(data); @@ -223,7 +223,7 @@ int flash_load(flash_file_t *ctx, const char *name, int can_write_bl) { } num_phdrs = le16(ehdr.e_phnum); - phdrs = malloc(le16(ehdr.e_phnum) * sizeof(Elf32_Phdr)); + phdrs = calloc(le16(ehdr.e_phnum) * sizeof(Elf32_Phdr), sizeof(uint8_t)); if (!phdrs) { fprintf(stderr, "Out of memory\n"); goto fail; diff --git a/client/fpga_compress.c b/client/fpga_compress.c index ceba6ac64..6e6e67be4 100644 --- a/client/fpga_compress.c +++ b/client/fpga_compress.c @@ -59,7 +59,7 @@ static void usage(void) static voidpf fpga_deflate_malloc(voidpf opaque, uInt items, uInt size) { - return malloc(items*size); + return calloc(items*size, sizeof(uint8_t)); } @@ -89,9 +89,9 @@ int zlib_compress(FILE *infile[], uint8_t num_infiles, FILE *outfile, bool hardn z_stream compressed_fpga_stream; if (hardnested_mode) { - fpga_config = malloc(num_infiles * HARDNESTED_TABLE_SIZE); + fpga_config = calloc(num_infiles * HARDNESTED_TABLE_SIZE, sizeof(uint8_t)); } else { - fpga_config = malloc(num_infiles * FPGA_CONFIG_SIZE); + fpga_config = calloc(num_infiles * FPGA_CONFIG_SIZE, sizeof(uint8_t)); } // read the input files. Interleave them into fpga_config[] i = 0; diff --git a/client/hid-flasher/flash.c b/client/hid-flasher/flash.c index e74f4ed49..c53e560d5 100644 --- a/client/hid-flasher/flash.c +++ b/client/hid-flasher/flash.c @@ -40,7 +40,7 @@ static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs, flash_seg_t *seg; uint32_t last_end = 0; - ctx->segments = malloc(sizeof(flash_seg_t) * num_phdrs); + ctx->segments = calloc(sizeof(flash_seg_t) * num_phdrs, sizeof(uint8_t)); if (!ctx->segments) { fprintf(stderr, "Out of memory\n"); return -1; @@ -90,7 +90,7 @@ static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs, uint8_t *data; // make extra space if we need to move the data forward - data = malloc(filesz + BLOCK_SIZE); + data = calloc(filesz + BLOCK_SIZE, sizeof(uint8_t)); if (!data) { fprintf(stderr, "Out of memory\n"); return -1; @@ -226,7 +226,7 @@ int flash_load(flash_file_t *ctx, const char *name, int can_write_bl) } num_phdrs = le16(ehdr.e_phnum); - phdrs = malloc(le16(ehdr.e_phnum) * sizeof(Elf32_Phdr)); + phdrs = calloc(le16(ehdr.e_phnum) * sizeof(Elf32_Phdr), sizeof(uint8_t)); if (!phdrs) { fprintf(stderr, "Out of memory\n"); goto fail; diff --git a/client/loclass/cipher.c b/client/loclass/cipher.c index af11ce4cc..e8553ba6c 100644 --- a/client/loclass/cipher.c +++ b/client/loclass/cipher.c @@ -224,7 +224,7 @@ void doMAC(uint8_t *cc_nr_p, uint8_t *div_key_p, uint8_t mac[4]) { uint8_t cc_nr[13] = { 0 }; uint8_t div_key[8]; - //cc_nr=(uint8_t*)malloc(length+1); + //cc_nr=(uint8_t*) calloc(length+1, sizeof(uint8_t)); memcpy(cc_nr, cc_nr_p, 12); memcpy(div_key, div_key_p, 8); @@ -244,7 +244,7 @@ void doMAC_N(uint8_t *address_data_p, uint8_t address_data_size, uint8_t *div_ke { uint8_t *address_data; uint8_t div_key[8]; - address_data = (uint8_t*) malloc(address_data_size); + address_data = (uint8_t*) calloc(address_data_size, sizeof(uint8_t)); memcpy(address_data, address_data_p, address_data_size); memcpy(div_key, div_key_p, 8); diff --git a/client/loclass/cipherutils.h b/client/loclass/cipherutils.h index 568671791..21d11aac0 100644 --- a/client/loclass/cipherutils.h +++ b/client/loclass/cipherutils.h @@ -52,7 +52,7 @@ typedef struct { uint8_t * buffer; uint8_t numbits; uint8_t position; -}BitstreamOut; +} BitstreamOut; bool headBit( BitstreamIn *stream); bool tailBit( BitstreamIn *stream); diff --git a/client/loclass/elite_crack.c b/client/loclass/elite_crack.c index 2002e348f..6619e7aaa 100644 --- a/client/loclass/elite_crack.c +++ b/client/loclass/elite_crack.c @@ -493,7 +493,7 @@ int bruteforceDump(uint8_t dump[], size_t dumpsize, uint16_t keytable[]) { uint64_t t1 = msclock(); - dumpdata* attack = (dumpdata* ) malloc(itemsize); + dumpdata* attack = (dumpdata* ) calloc(itemsize, sizeof(uint8_t)); for (i = 0 ; i * itemsize < dumpsize ; i++ ) { memcpy(attack, dump + i * itemsize, itemsize); diff --git a/client/loclass/fileutils.c b/client/loclass/fileutils.c index 5bac3d2cd..da91b21ec 100644 --- a/client/loclass/fileutils.c +++ b/client/loclass/fileutils.c @@ -71,14 +71,14 @@ int saveFile(const char *preferredName, const char *suffix, const void* data, si /*Opening file for writing in binary mode*/ FILE *f = fopen(fileName, "wb"); if (!f) { - PrintAndLogDevice(WARNING, "file not found or locked. '%s'", fileName); + PrintAndLogDevice(WARNING, "file not found or locked. '" _YELLOW_(%s)"'", fileName); free(fileName); return 1; } fwrite(data, 1, datalen, f); fflush(f); fclose(f); - PrintAndLogDevice(SUCCESS, "saved %u bytes to binary file %s", datalen, fileName); + PrintAndLogDevice(SUCCESS, "saved %u bytes to binary file " _YELLOW_(%s), datalen, fileName); free(fileName); return 0; } @@ -106,8 +106,8 @@ int saveFileEML(const char *preferredName, const char *suffix, uint8_t* data, si /*Opening file for writing in text mode*/ FILE *f = fopen(fileName, "w+"); - if (!f) { - PrintAndLogDevice(WARNING, "file not found or locked. '%s'", fileName); + if (!f) { + PrintAndLogDevice(WARNING, "file not found or locked. '" _YELLOW_(%s)"'", fileName); retval = 1; goto out; } @@ -130,7 +130,7 @@ int saveFileEML(const char *preferredName, const char *suffix, uint8_t* data, si } fflush(f); fclose(f); - PrintAndLogDevice(SUCCESS, "saved %d blocks to text file %s", blocks, fileName); + PrintAndLogDevice(SUCCESS, "saved %d blocks to text file " _YELLOW_(%s), blocks, fileName); out: free(fileName); @@ -240,13 +240,12 @@ int saveFileJSON(const char *preferredName, const char *suffix, JSONFileType fty int res = json_dump_file(root, fileName, JSON_INDENT(2)); if (res) { - PrintAndLogDevice(FAILED, "error: can't save the file: %s", fileName); + PrintAndLogDevice(FAILED, "error: can't save the file: " _YELLOW_(%s), fileName); json_decref(root); retval = 200; goto out; } - PrintAndLogDevice(SUCCESS, "File `%s` saved.", fileName); - + PrintAndLogDevice(SUCCESS, "saved to json file " _YELLOW_(%s), fileName); json_decref(root); out: @@ -266,7 +265,7 @@ int loadFile(const char *preferredName, const char *suffix, void* data, size_t* FILE *f = fopen(fileName, "rb"); if ( !f ) { - PrintAndLogDevice(FAILED, "file: %s: not found or locked.", fileName); + PrintAndLogDevice(WARNING, "file not found or locked. '" _YELLOW_(%s)"'", fileName); retval = 1; goto out; } @@ -305,7 +304,7 @@ int loadFile(const char *preferredName, const char *suffix, void* data, size_t* memcpy( (data), dump, bytes_read); free(dump); - PrintAndLogDevice(SUCCESS, "loaded %d bytes from binary file %s", bytes_read, fileName); + PrintAndLogDevice(SUCCESS, "loaded %d bytes from binary file " _YELLOW_(%s), bytes_read, fileName); *datalen = bytes_read; @@ -328,7 +327,7 @@ int loadFileEML(const char *preferredName, const char *suffix, void* data, size_ FILE *f = fopen(fileName, "r"); if ( !f ) { - PrintAndLogDevice(FAILED, "file: %s: not found or locked.", fileName); + PrintAndLogDevice(WARNING, "file not found or locked. '" _YELLOW_(%s)"'", fileName); retval = 1; goto out; } @@ -359,7 +358,7 @@ int loadFileEML(const char *preferredName, const char *suffix, void* data, size_ } } fclose(f); - PrintAndLogDevice(SUCCESS, "loaded %d bytes from text file %s", counter, fileName); + PrintAndLogDevice(SUCCESS, "loaded %d bytes from text file " _YELLOW_(%s), counter, fileName); *datalen = counter; out: @@ -382,13 +381,13 @@ int loadFileJSON(const char *preferredName, const char *suffix, void* data, size root = json_load_file(fileName, 0, &error); if (!root) { - PrintAndLog("ERROR: json (%s) error on line %d: %s", fileName, error.line, error.text); + PrintAndLog("ERROR: json " _YELLOW_(%s) " error on line %d: %s", fileName, error.line, error.text); retval = 2; goto out; } if (!json_is_object(root)) { - PrintAndLog("ERROR: Invalid json (%s) format. root must be an object.", fileName); + PrintAndLog("ERROR: Invalid json " _YELLOW_(%s) " format. root must be an object.", fileName); retval = 3; goto out; } @@ -446,7 +445,7 @@ int loadFileJSON(const char *preferredName, const char *suffix, void* data, size } - PrintAndLog("Loaded JSON: (%s) OK.", fileName); + PrintAndLog("loaded from JSON file " _YELLOW_(%s), fileName); out: json_decref(root); free(fileName); @@ -479,7 +478,7 @@ int loadFileDICTIONARY(const char *preferredName, const char *suffix, void* data FILE *f = fopen(fileName, "r"); if ( !f ) { - PrintAndLogDevice(FAILED, "file: %s: not found or locked.", fileName); + PrintAndLogDevice(WARNING, "file not found or locked. '" _YELLOW_(%s)"'", fileName); retval = 1; goto out; } @@ -512,7 +511,7 @@ int loadFileDICTIONARY(const char *preferredName, const char *suffix, void* data counter += (keylen >> 1); } fclose(f); - PrintAndLogDevice(SUCCESS, "loaded " _GREEN_(%2d) "keys from dictionary file %s", *keycnt, fileName); + PrintAndLogDevice(SUCCESS, "loaded " _GREEN_(%2d) "keys from dictionary file " _YELLOW_(%s), *keycnt, fileName); *datalen = counter; out: free(fileName); diff --git a/client/lualibs/taglib.lua b/client/lualibs/taglib.lua index f421ab22f..97194714c 100644 --- a/client/lualibs/taglib.lua +++ b/client/lualibs/taglib.lua @@ -1,72 +1,115 @@ -local manufacturer = {} -manufacturer[0x01]='Motorola [UK]' -manufacturer[0x02]='STMicroelectronics SA [France]' -manufacturer[0x03]='Hitachi, Ltd [Japan]' -manufacturer[0x04]='NXP Semiconductors [Germany]' -manufacturer[0x05]='Infineon Technologies AG [Germany]' -manufacturer[0x06]='Cylink [USA]' -manufacturer[0x07]='Texas Instrument [France]' -manufacturer[0x08]='Fujitsu Limited [Japan]' -manufacturer[0x09]='Matsushita Electronics Corporation, Semiconductor Company [Japan]' -manufacturer[0x0A]='NEC [Japan]' -manufacturer[0x0B]='Oki Electric Industry Co. Ltd [Japan]' -manufacturer[0x0C]='Toshiba Corp. [Japan]' -manufacturer[0x0D]='Mitsubishi Electric Corp. [Japan]' -manufacturer[0x0E]='Samsung Electronics Co. Ltd [Korea]' -manufacturer[0x0F]='Hynix [Korea]' -manufacturer[0x10]='LG-Semiconductors Co. Ltd [Korea]' -manufacturer[0x11]='Emosyn-EM Microelectronics [USA]' -manufacturer[0x12]='INSIDE Technology [France]' -manufacturer[0x13]='ORGA Kartensysteme GmbH [Germany]' -manufacturer[0x14]='SHARP Corporation [Japan]' -manufacturer[0x15]='ATMEL [France]' -manufacturer[0x16]='EM Microelectronic-Marin SA [Switzerland]' -manufacturer[0x17]='KSW Microtec GmbH [Germany]' -manufacturer[0x18]='ZMD AG [Germany]' -manufacturer[0x19]='XICOR, Inc. [USA]' -manufacturer[0x1A]='Sony Corporation [Japan]' -manufacturer[0x1B]='Malaysia Microelectronic Solutions Sdn. Bhd [Malaysia]' -manufacturer[0x1C]='Emosyn [USA]' -manufacturer[0x1D]='Shanghai Fudan Microelectronics Co. Ltd. P.R. [China]' -manufacturer[0x1E]='Magellan Technology Pty Limited [Australia]' -manufacturer[0x1F]='Melexis NV BO [Switzerland]' -manufacturer[0x20]='Renesas Technology Corp. [Japan]' -manufacturer[0x21]='TAGSYS [France]' -manufacturer[0x22]='Transcore [USA]' -manufacturer[0x23]='Shanghai belling corp., ltd. [China]' -manufacturer[0x24]='Masktech Germany Gmbh [Germany]' -manufacturer[0x25]='Innovision Research and Technology Plc [UK]' -manufacturer[0x26]='Hitachi ULSI Systems Co., Ltd. [Japan]' -manufacturer[0x27]='Cypak AB [Sweden]' -manufacturer[0x28]='Ricoh [Japan]' -manufacturer[0x29]='ASK [France]' -manufacturer[0x2A]='Unicore Microsystems, LLC [RussianFederation]' -manufacturer[0x2B]='Dallas Semiconductor/Maxim [USA]' -manufacturer[0x2C]='Impinj, Inc. [USA]' -manufacturer[0x2D]='RightPlug Alliance [USA]' -manufacturer[0x2E]='Broadcom Corporation [USA]' -manufacturer[0x2F]='MStar Semiconductor, Inc Taiwan, [ROC]' -manufacturer[0x30]='BeeDar Technology Inc. [USA]' -manufacturer[0x31]='RFIDsec [Denmark]' -manufacturer[0x32]='Schweizer Electronic AG [Germany]' -manufacturer[0x33]='AMIC Technology Corp [Taiwan]' -manufacturer[0x34]='Mikron JSC [Russia]' -manufacturer[0x35]='Fraunhofer Institute for Photonic Microsystems [Germany]' -manufacturer[0x36]='IDS Microchip AG [Switzerland]' -manufacturer[0x37]='Kovio [USA]' -manufacturer[0x38]='HMT Microelectronic Ltd [Switzerland]' -manufacturer[0x39]='Silicon Craft Technology [Thailand]' -manufacturer[0x3A]='Advanced Film Device Inc. [Japan]' -manufacturer[0x3B]='Nitecrest Ltd [UK]' -manufacturer[0x3C]='Verayo Inc. [USA]' -manufacturer[0x3D]='HID Global [USA]' -manufacturer[0x3E]='Productivity Engineering Gmbh [Germany]' -manufacturer[0x3F]='Austriamicrosystems AG (reserved) [Austria]' -manufacturer[0x40]='Gemalto SA [France]' -manufacturer[0x41]='Renesas Electronics Corporation [Japan]' -manufacturer[0x42]='3Alogics Inc [Korea]' -manufacturer[0x43]='Top TroniQ Asia Limited Hong [Kong]' -manufacturer[0x44]='Gentag Inc (USA) [USA]' +local m = {} +m[0x01]='Motorola UK' +m[0x02]='ST Microelectronics SA France' +m[0x03]='Hitachi, Ltd Japan' +m[0x04]='NXP Semiconductors Germany' +m[0x05]='Infineon Technologies AG Germany' +m[0x06]='Cylink USA' +m[0x07]='Texas Instrument France' +m[0x08]='Fujitsu Limited Japan' +m[0x09]='Matsushita Electronics Corporation, Semiconductor Company Japan' +m[0x0A]='NEC Japan' +m[0x0B]='Oki Electric Industry Co. Ltd Japan' +m[0x0C]='Toshiba Corp. Japan' +m[0x0D]='Mitsubishi Electric Corp. Japan' +m[0x0E]='Samsung Electronics Co. Ltd Korea' +m[0x0F]='Hynix / Hyundai, Korea' +m[0x10]='LG-Semiconductors Co. Ltd Korea' +m[0x11]='Emosyn-EM Microelectronics USA' +m[0x12]='INSIDE Technology France' +m[0x13]='ORGA Kartensysteme GmbH Germany' +m[0x14]='SHARP Corporation Japan' +m[0x15]='ATMEL France' +m[0x16]='EM Microelectronic-Marin SA Switzerland' +m[0x17]='KSW Microtec GmbH Germany' +m[0x18]='ZMD AG Germany' +m[0x19]='XICOR, Inc. USA' +m[0x1A]='Sony Corporation Japan' +m[0x1B]='Malaysia Microelectronic Solutions Sdn. Bhd Malaysia' +m[0x1C]='Emosyn USA' +m[0x1D]='Shanghai Fudan Microelectronics Co. Ltd. P.R. China' +m[0x1E]='Magellan Technology Pty Limited Australia' +m[0x1F]='Melexis NV BO Switzerland' +m[0x20]='Renesas Technology Corp. Japan' +m[0x21]='TAGSYS France' +m[0x22]='Transcore USA' +m[0x23]='Shanghai belling corp., ltd. China' +m[0x24]='Masktech Germany Gmbh Germany' +m[0x25]='Innovision Research and Technology Plc UK' +m[0x26]='Hitachi ULSI Systems Co., Ltd. Japan' +m[0x27]='Cypak AB Sweden' +m[0x28]='Ricoh Japan' +m[0x29]='ASK France' +m[0x2A]='Unicore Microsystems, LLC RussianFederation' +m[0x2B]='Dallas Semiconductor/Maxim USA' +m[0x2C]='Impinj, Inc. USA' +m[0x2D]='RightPlug Alliance USA' +m[0x2E]='Broadcom Corporation USA' +m[0x2F]='MStar Semiconductor, Inc Taiwan, ROC' +m[0x30]='BeeDar Technology Inc. USA' +m[0x31]='RFIDsec Denmark' +m[0x32]='Schweizer Electronic AG Germany' +m[0x33]='AMIC Technology Corp Taiwan' +m[0x34]='Mikron JSC Russia' +m[0x35]='Fraunhofer Institute for Photonic Microsystems Germany' +m[0x36]='IDS Microchip AG Switzerland' +m[0x37]='Kovio USA' +m[0x38]='HMT Microelectronic Ltd Switzerland' +m[0x39]='Silicon Craft Technology Thailand' +m[0x3A]='Advanced Film Device Inc. Japan' +m[0x3B]='Nitecrest Ltd UK' +m[0x3C]='Verayo Inc. USA' +m[0x3D]='HID Global USA' +m[0x3E]='Productivity Engineering Gmbh Germany' +m[0x3F]='Austriamicrosystems AG (reserved) Austria' +m[0x40]='Gemalto SA France' +m[0x41]='Renesas Electronics Corporation Japan' +m[0x42]='3Alogics Inc Korea' +m[0x43]='Top TroniQ Asia Limited Hong Kong' +m[0x44]='Gentag Inc USA' +m[0x45]='Invengo Information Technology Co.Ltd China' +m[0x46]='Guangzhou Sysur Microelectronics, Inc China' +m[0x47]='CEITEC S.A. Brazil' +m[0x48]='Shanghai Quanray Electronics Co. Ltd. China' +m[0x49]='MediaTek Inc Taiwan' +m[0x4A]='Angstrem PJSC Russia' +m[0x4B]='Celisic Semiconductor (Hong Kong) Limited China' +m[0x4C]='LEGIC Identsystems AG Switzerland' +m[0x4D]='Balluff GmbH Germany' +m[0x4E]='Oberthur Technologies France' +m[0x4F]='Silterra Malaysia Sdn. Bhd. Malaysia' +m[0x50]='DELTA Danish Electronics, Light & Acoustics Denmark' +m[0x51]='Giesecke & Devrient GmbH Germany' +m[0x52]='Shenzhen China Vision Microelectronics Co., Ltd. China' +m[0x53]='Shanghai Feiju Microelectronics Co. Ltd. China' +m[0x54]='Intel Corporation USA' +m[0x55]='Microsensys GmbH Germany' +m[0x56]='Sonix Technology Co., Ltd. Taiwan' +m[0x57]='Qualcomm Technologies Inc USA' +m[0x58]='Realtek Semiconductor Corp Taiwan' +m[0x59]='Freevision Technologies Co. Ltd China' +m[0x5A]='Giantec Semiconductor Inc. China' +m[0x5B]='JSC Angstrem-T Russia' +m[0x5C]='STARCHIP France' +m[0x5D]='SPIRTECH France' +m[0x5E]='GANTNER Electronic GmbH Austria' +m[0x5F]='Nordic Semiconductor Norway' +m[0x60]='Verisiti Inc USA' +m[0x61]='Wearlinks Technology Inc. China' +m[0x62]='Userstar Information Systems Co., Ltd Taiwan' +m[0x63]='Pragmatic Printing Ltd. UK' +m[0x64]='Associacao do Laboratorio de Sistemas Integraveis Tecnologico – LSI-TEC Brazil' +m[0x65]='Tendyron Corporation China' +m[0x66]='MUTO Smart Co., Ltd. Korea' +m[0x67]='ON Semiconductor USA' +m[0x68]='TUBITAK BILGEM Turkey' +m[0x69]='Huada Semiconductor Co., Ltd China' +m[0x6A]='SEVENEY France' +m[0x6B]='ISSM France' +m[0x6C]='Wisesec Ltd Israel' +m[0x7C]='DB HiTek Co Ltd Korea' +m[0x7D]='SATO Vicinity Australia' +m[0x7E]='Holtek Taiwan' return { lookupManufacturer = function (value) @@ -76,8 +119,6 @@ return { value = v end - return manufacturer[value] or "no tag-info available" + return m[value] or "no tag-info available" end, - - } \ No newline at end of file diff --git a/client/mifarehost.c b/client/mifarehost.c index 0f37f8a8b..31ed8e39d 100644 --- a/client/mifarehost.c +++ b/client/mifarehost.c @@ -173,18 +173,19 @@ int mfCheckKeys_fast( uint8_t sectorsCnt, uint8_t firstChunk, uint8_t lastChunk, // success array. each byte is status of key uint8_t arr[80]; - uint64_t foo = bytes_to_num(resp.d.asBytes+480, 8); - for (uint8_t i = 0; i < 64; ++i) { - arr[i] = (foo >> i) & 0x1; - } - foo = bytes_to_num(resp.d.asBytes+488, 2); - for (uint8_t i = 0; i < 16; ++i) { - arr[i+64] = (foo >> i) & 0x1; - } + uint64_t foo = 0; + uint16_t bar = 0; + foo = bytes_to_num(resp.d.asBytes+480, 8); + bar = (resp.d.asBytes[489] << 8 | resp.d.asBytes[488]); + for (uint8_t i = 0; i < 64; i++) + arr[i] = (foo >> i) & 0x1; + + for (uint8_t i = 0; i < 16; i++) + arr[i+64] = (bar >> i) & 0x1; + // initialize storage for found keys - icesector_t *tmp = NULL; - tmp = calloc(sectorsCnt, sizeof(icesector_t)); + icesector_t *tmp = calloc(sectorsCnt, sizeof(icesector_t)); if (tmp == NULL) return 1; memcpy(tmp, resp.d.asBytes, sectorsCnt * sizeof(icesector_t) ); diff --git a/client/proxmark3.c b/client/proxmark3.c index ed7fd245d..246da350b 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -215,11 +215,11 @@ const char *get_my_executable_directory(void) { static void set_my_executable_path(void) { int path_length = wai_getExecutablePath(NULL, 0, NULL); if (path_length != -1) { - my_executable_path = (char*)malloc(path_length + 1); + my_executable_path = (char*)calloc(path_length + 1, sizeof(uint8_t)); int dirname_length = 0; if (wai_getExecutablePath(my_executable_path, path_length, &dirname_length) != -1) { my_executable_path[path_length] = '\0'; - my_executable_directory = (char *)malloc(dirname_length + 2); + my_executable_directory = (char *)calloc(dirname_length + 2, sizeof(uint8_t)); strncpy(my_executable_directory, my_executable_path, dirname_length+1); my_executable_directory[dirname_length+1] = '\0'; } @@ -321,9 +321,9 @@ int main(int argc, char* argv[]) { } else { if (addLuaExec){ // add "script run " to command - char *ctmp = NULL; int len = strlen(script_cmd) + 11 + 1; - if ((ctmp = (char*) malloc(len)) != NULL) { + char *ctmp = (char*) calloc(len, sizeof(uint8_t)); + if (ctmp != NULL) { memset(ctmp, 0, len); strcpy(ctmp, "script run "); strcpy(&ctmp[11], script_cmd); diff --git a/client/reveng/cli.c b/client/reveng/cli.c index f4b40856a..6e147ba20 100644 --- a/client/reveng/cli.c +++ b/client/reveng/cli.c @@ -377,7 +377,9 @@ ipqx: /* allocate argument array */ args = argc - optind; - if(!(apolys = malloc(args * sizeof(poly_t)))){ + + apolys = calloc(args * sizeof(poly_t), sizeof(char)); + if ( !apolys ){ uerror("cannot allocate memory for argument list"); return 0; } diff --git a/client/reveng/model.c b/client/reveng/model.c index f99b1ee02..2c58d695a 100644 --- a/client/reveng/model.c +++ b/client/reveng/model.c @@ -118,7 +118,7 @@ char * mtostr(const model_t *model) { + (checkstr && *checkstr ? strlen(checkstr) : 6) + (magicstr && *magicstr ? strlen(magicstr) : 6) + (model->name && *model->name ? 2 + strlen(model->name) : 6); - if ((string = malloc(size))) { + if ((string = calloc(size, sizeof(uint8_t)))) { sprintf(strbuf, "\"%s\"", model->name); sprintf(string, "width=%lu " diff --git a/client/reveng/poly.c b/client/reveng/poly.c index 011a09978..7056c118a 100644 --- a/client/reveng/poly.c +++ b/client/reveng/poly.c @@ -349,7 +349,7 @@ pxsubs(const poly_t poly, int flags, int bperhx, unsigned long start, unsigned l size *= cperhx; if(!size || ~flags & P_SPACE) ++size; /* for trailing null */ - if(!(sptr = string = (char *) malloc(size))) + if(!(sptr = string = (char *) calloc(size, sizeof(char)))) uerror("cannot allocate memory for string"); size = end - start; diff --git a/client/reveng/preset.c b/client/reveng/preset.c index 6dbedaed9..82a18b977 100644 --- a/client/reveng/preset.c +++ b/client/reveng/preset.c @@ -811,7 +811,9 @@ int mbynam(model_t *dest, const char *key) { if (!aliases->name) return(-1); - if (!(ukey = malloc((size_t) 1 + strlen(key) + 1))) { + + ukey = calloc((size_t) 1 + strlen(key) + 1, sizeof(char)); + if (!ukey) { uerror("[!] cannot allocate memory for comparison string"); return(0); } @@ -861,7 +863,9 @@ char * mnames(void) { ++aptr; } if (!size) return(NULL); - if ((string = malloc(size))) { + + string = calloc(size, sizeof(char)); + if (string) { aptr = aliases; sptr = string; while (aptr->name) { diff --git a/client/reveng/reveng.c b/client/reveng/reveng.c index 004a6fc3c..550dc2da5 100644 --- a/client/reveng/reveng.c +++ b/client/reveng/reveng.c @@ -173,8 +173,9 @@ modpol(const poly_t init, int rflags, int args, const poly_t *argpolys) { unsigned long alen, blen; if(args < 2) return(NULL); - - if(!(result = malloc(((((args - 1) * args) >> 1) + 1) * sizeof(poly_t)))) + + result = calloc(((((args - 1) * args) >> 1) + 1) * sizeof(poly_t), sizeof(char)); + if(!result) uerror("cannot allocate memory for codeword table"); rptr = result; @@ -240,7 +241,8 @@ engini(int *resc, model_t **result, const poly_t divisor, int flags, int args, c dlen = plen(divisor); /* Allocate the CRC matrix */ - if(!(mat = (poly_t *) malloc((dlen << 1) * sizeof(poly_t)))) + mat = (poly_t *) calloc((dlen << 1) * sizeof(poly_t), sizeof(char)); + if(!mat) uerror("cannot allocate memory for CRC matrix"); /* Find arguments of the two shortest lengths */ diff --git a/client/scandir.c b/client/scandir.c index 12bbef110..619bd72c6 100644 --- a/client/scandir.c +++ b/client/scandir.c @@ -51,7 +51,8 @@ int scandir (const char *dir, nl = ntmp; } - if (!(etmp = (struct dirent *) malloc (sizeof *ent))) { + etmp = (struct dirent *) calloc (sizeof *ent, sizeof(char)); + if (!etmp) { err_no = 1; break; } diff --git a/client/scripting.c b/client/scripting.c index 3d3518ced..b6bb80f33 100644 --- a/client/scripting.c +++ b/client/scripting.c @@ -758,6 +758,15 @@ int set_pm3_libraries(lua_State *L) { //-- remove the global environment table from the stack lua_pop(L, 1); + + //--add to the LUA_PATH (package.path in lua) + // so we can load scripts from the ./scripts/ - directory + char scripts_path[strlen(get_my_executable_directory()) + strlen(LUA_SCRIPTS_DIRECTORY) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; + strcpy(scripts_path, get_my_executable_directory()); + strcat(scripts_path, LUA_SCRIPTS_DIRECTORY); + strcat(scripts_path, LUA_LIBRARIES_WILDCARD); + setLuaPath(L, scripts_path); + //-- Last but not least, add to the LUA_PATH (package.path in lua) // so we can load libraries from the ./lualib/ - directory char libraries_path[strlen(get_my_executable_directory()) + strlen(LUA_LIBRARIES_DIRECTORY) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; @@ -765,6 +774,5 @@ int set_pm3_libraries(lua_State *L) { strcat(libraries_path, LUA_LIBRARIES_DIRECTORY); strcat(libraries_path, LUA_LIBRARIES_WILDCARD); setLuaPath(L, libraries_path); - return 1; } \ No newline at end of file diff --git a/client/scripts/iso15_magic.lua b/client/scripts/iso15_magic.lua index 36e8100a8..3923f2b1e 100644 --- a/client/scripts/iso15_magic.lua +++ b/client/scripts/iso15_magic.lua @@ -5,7 +5,7 @@ local utils = require('utils') copyright = 'Copyright (c) 2018 IceSQL AB. All rights reserved.' author = 'Christian Herrmann' -version = 'v1.0.3' +version = 'v1.0.4' desc = [[ This script tries to set UID on a IS15693 SLIX magic card Remember the UID ->MUST<- start with 0xE0 @@ -15,6 +15,8 @@ example = [[ -- ISO15693 slix magic tag script run iso15_magic -u E004013344556677 + + script run iso15_magic -u E004013344556677 -a ]] usage = [[ script run iso15_magic -h -u @@ -22,6 +24,7 @@ script run iso15_magic -h -u Arguments: -h : this help -u : UID (16 hexsymbols) + -a : use offical pm3 repo ISO15 commands instead of iceman fork. ]] local DEBUG = true @@ -82,11 +85,13 @@ function main(args) print() local uid = 'E004013344556677' + local use_iceman = true -- Read the parameters - for o, a in getopt.getopt(args, 'hu:') do + for o, a in getopt.getopt(args, 'hu:a') do if o == "h" then return help() end if o == "u" then uid = a end + if o == "a" then use_iceman = false end end -- uid string checks @@ -103,8 +108,11 @@ function main(args) core.clearCommandBuffer() - magicUID_iceman(block0, block1) - --magicUID_offical(block0, block1) + if use_iceman then + magicUID_iceman(block0, block1) + else + magicUID_offical(block0, block1) + end end main(args) diff --git a/client/scripts/legic.lua b/client/scripts/legic.lua index 546e5cc1a..264d4dfef 100644 --- a/client/scripts/legic.lua +++ b/client/scripts/legic.lua @@ -513,8 +513,8 @@ function readFromPM3() return tag end -function padString(str) - if (str:len() == 1) then +local function padString(str) + if (#str == 1) then return '0'..str end @@ -524,73 +524,84 @@ end --- -- write virtual Tag to real Tag function writeToTag(tag) - local bytes - local filename='MylegicClone.hex' - local taglen=22 + local bytes + local filename = 'MylegicClone.hex' + local taglen = 22 if(utils.confirm(acred.."\nplace the (empty) Tag onto the PM3\nand confirm writing to this Tag: "..acoff) == false) then - return - end - -- get used bytes / tag-len - if(istable(tag.SEG)) then - if (istable(tag.Bck)) then - for i=0, #tag.SEG do - taglen=taglen+tag.SEG[i].len+5 - end - end - local uid_old=tag.MCD..tag.MSN0..tag.MSN1..tag.MSN2 - -- read new tag into memory so we can xor the new data with the new MCC - outTAG=readFromPM3() - outbytes=tagToBytes(outTAG) - -- copy 'inputbuffer' to 'outputbuffer' - tag.MCD = outbytes[1] - tag.MSN0 = outbytes[2] - tag.MSN1 = outbytes[3] - tag.MSN2 = outbytes[4] - tag.MCC = outbytes[5] - -- recheck all segments-crc/kghcrc (only on a credential) - if(istable(tag.Bck)) then - checkAllSegCrc(tag) - checkAllKghCrc(tag) - local uid_new=tag.MCD..tag.MSN0..tag.MSN1..tag.MSN2 - for i=0, #tag.SEG do - if (check43rdPartyCash1(uid_old, tag.SEG[i].data)) then - io.write(accyan.."\nfixing known checksums"..acoff.." ... ") - if (fix3rdPartyCash1(uid_new, tag.SEG[i].data)) then - io.write(acgreen.." done\n"..acoff) - else oops("\nsomething went wrong at the repair of the 3rd-party-cash-segment") end - end - end - end - bytes=tagToBytes(tag) - -- master-token-crc - if (tag.Type ~= "SAM") then bytes[22] = calcMtCrc(bytes) end - if (bytes) then - print("write temp-file '"..filename.."'") - print(accyan) - writeFile(bytes, filename..".bin") - print(acoff) - end - end + return + end + + -- get used bytes / tag-len + if (istable(tag.SEG)) then + if (istable(tag.Bck)) then + for i=0, #tag.SEG do + taglen = taglen + tag.SEG[i] . len + 5 + end + end + local uid_old = tag.MCD..tag.MSN0..tag.MSN1..tag.MSN2 + + -- read new tag into memory so we can xor the new data with the new MCC + outTAG = readFromPM3() + outbytes = tagToBytes(outTAG) + -- copy 'inputbuffer' to 'outputbuffer' + tag.MCD = outbytes[1] + tag.MSN0 = outbytes[2] + tag.MSN1 = outbytes[3] + tag.MSN2 = outbytes[4] + tag.MCC = outbytes[5] + -- recheck all segments-crc/kghcrc (only on a credential) + if (istable(tag.Bck)) then + checkAllSegCrc(tag) + checkAllKghCrc(tag) + local uid_new = tag.MCD..tag.MSN0..tag.MSN1..tag.MSN2 + for i=0, #tag.SEG do + if (check43rdPartyCash1(uid_old, tag.SEG[i].data)) then + io.write(accyan.."\nfixing known checksums"..acoff.." ... ") + if (fix3rdPartyCash1(uid_new, tag.SEG[i].data)) then + io.write(acgreen.." done\n"..acoff) + else + oops("\nsomething went wrong at the repair of the 3rd-party-cash-segment") + end + end + end + end + bytes = tagToBytes(tag) + -- master-token-crc + if (tag.Type ~= "SAM") then + bytes[22] = calcMtCrc(bytes) + end + if (bytes) then + print("write temp-file '"..filename.."'") + print(accyan) + writeFile(bytes, filename..".bin") + print(acoff) + end + end - -- write data to file + -- write data to file if (taglen > 0) then WriteBytes = utils.input(acyellow.."enter number of bytes to write?"..acoff, taglen) -- load file into pm3-buffer - if (type(filename) ~= "string") then filename=input(acyellow.."filename to load to pm3-buffer?"..acoff,"legic.temp") end + if (type(filename) ~= "string") then + filename = input(acyellow.."filename to load to pm3-buffer?"..acoff, "legic.temp") + end + cmd = 'hf legic eload 2 '..filename core.console(cmd) -- write pm3-buffer to Tag for i=0, WriteBytes do if (i > 6) then - cmd = 'hf legic write o '..string.format("%x", i)..' d '..padString(bytes[i]) - print(acgreen..cmd..acoff) + cmd = ("hf legic write o %x d %s "):format(i, padString(bytes[i])) + print(acgreen..cmd..acoff) core.console(cmd) + core.clearCommandBuffer() elseif (i == 6) then - -- write DCF in reverse order (requires 'mosci-patch') - cmd = 'hf legic write o 05 d '..padString(bytes[i-1])..padString(bytes[i]) - print(acgreen..cmd..acoff) + -- write DCF in reverse order (requires 'mosci-patch') + cmd = ('hf legic write o 05 d %s%s'):format(padString(bytes[i-1]), padString(bytes[i])) + print(acgreen..cmd..acoff) core.console(cmd) - elseif (i == 5) then + core.clearCommandBuffer() + elseif (i == 5) then print(acgreen.."skip byte 0x05 - will be written next step"..acoff) else print(acgreen.."skip byte 0x00-0x04 - unwritable area"..acoff) @@ -603,26 +614,28 @@ end --- File I/O --- --- -- read file into virtual-tag -function readFile(filename) - print(accyan) - local bytes = {} - local tag = {} - if file_check(filename) == false then return oops("input file: "..filename.." not found") end +local function readFile(filename) + print(accyan) + local bytes = {} + local tag = {} + if file_check(filename) == false then + return oops("input file: "..filename.." not found") + end - bytes = getInputBytes(filename) + bytes = getInputBytes(filename) - if bytes == false then return oops('couldnt get input bytes') end + if bytes == false then return oops('couldnt get input bytes') end - -- make plain bytes - bytes = xorBytes(bytes,bytes[5]) - print("create virtual tag from ".. #bytes .. " bytes") - -- create Tag for plain bytes - tag=createTagTable() - -- load plain bytes to tag-table - print(acoff) - tag=bytesToTag(bytes, tag) + -- make plain bytes + bytes = xorBytes(bytes,bytes[5]) + print("create virtual tag from ".. #bytes .. " bytes") + -- create Tag for plain bytes + tag = createTagTable() + -- load plain bytes to tag-table + print(acoff) + tag = bytesToTag(bytes, tag) - return tag + return tag end --- @@ -631,14 +644,16 @@ function writeFile(bytes, filename) if (filename ~= 'MylegicClone.hex') then if (file_check(filename)) then local answer = confirm("\nthe output-file "..filename.." already exists!\nthis will delete the previous content!\ncontinue?") - if (answer==false) then return print("user abort") end + if not answer then return print("user abort") end end end local line - local bcnt=0 - local fho,err = io.open(filename, "w") - if err then oops("OOps ... failed to open output-file ".. filename) end - bytes=xorBytes(bytes, bytes[5]) + local bcnt = 0 + local fho, err = io.open(filename, "w") + if err then + return oops("OOps ... failed to open output-file ".. filename) + end + bytes = xorBytes(bytes, bytes[5]) for i = 1, #bytes do if (bcnt == 0) then line = bytes[i] @@ -662,96 +677,96 @@ end --- Map related --- --- -- make tagMap -function makeTagMap() - local tagMap={} - if (#tagMap == 0) then - tagMap['name'] = input(accyan.."enter Name for this Map: "..acoff , "newTagMap") - tagMap['mappings']={} - tagMap['crc8']={} - -- insert fixed Tag-CRC - table.insert(tagMap.crc8, {name='TAG-CRC', pos=5, seq={1, 4}}) - tagMap['crc16']={} - end - print(accyan.."new tagMap created"..acoff) - return tagMap +local function makeTagMap() + local tagMap = {} + if (#tagMap == 0) then + tagMap['name'] = input(accyan.."enter Name for this Map: "..acoff , "newTagMap") + tagMap['mappings'] = {} + tagMap['crc8'] = {} + -- insert fixed Tag-CRC + table.insert(tagMap.crc8, {name = 'TAG-CRC', pos = 5, seq = {1, 4}}) + tagMap['crc16'] = {} + end + print(accyan.."new tagMap created"..acoff) + return tagMap end --- -- save mapping to file -function saveTagMap(map, filename) - if (string.len(filename)>0) then - if (file_check(filename)) then - local answer = confirm("\nthe output-file "..filename.." alredy exists!\nthis will delete the previous content!\ncontinue?") - if (answer==false) then return print("user abort") end - end - end +local function saveTagMap(map, filename) + if (string.len(filename)>0) then + if (file_check(filename)) then + local answer = confirm("\nthe output-file "..filename.." alredy exists!\nthis will delete the previous content!\ncontinue?") + if not answer then return print("user abort") end + end + end - local line + local line local fho,err = io.open(filename, "w") if err then oops("OOps ... faild to open output-file ".. filename) end - -- write line to new file - for k, v in pairs(map) do - if (istable(v)) then - for k2, v2 in pairs(v) do - if (k=='mappings') then - fho:write(k..","..k2..","..v2['name']..","..v2['start']..","..v2['end']..","..((v2['highlight']) and "1" or "0").."\n") - elseif (k=="crc8") then - local tmp="" - tmp=k..","..k2..","..v2['name']..","..v2['pos'].."," - tmp=tmp..tbl2seqstr(v2['seq']) - fho:write(tmp.."\n") - end - end - else - fho:write(k..","..v.."\n") - end - end + -- write line to new file + for k, v in pairs(map) do + if (istable(v)) then + for k2, v2 in pairs(v) do + if (k == 'mappings') then + fho:write(k..","..k2..","..v2['name']..","..v2['start']..","..v2['end']..","..((v2['highlight']) and "1" or "0").."\n") + elseif (k == "crc8") then + local tmp = "" + tmp = k..","..k2..","..v2['name']..","..v2['pos'].."," + tmp=tmp..tbl2seqstr(v2['seq']) + fho:write(tmp.."\n") + end + end + else + fho:write(k..","..v.."\n") + end + end fho:close() return true end --- -- toggle higligh -function toggleHighlight(tbl) +local function toggleHighlight(tbl) if (tbl['highlight']) then tbl['highlight'] = false else tbl['highlight'] = true end - return tbl + return tbl end --- -- return table od seqence-string -function seqstr2tbl(seqstr) - local s=split(seqstr) - local res={} - if (#s>=1) then - for sk, sv in pairs(s) do - s2=split(sv, '-') - if(#s2==2) then - table.insert(res, s2[1]) - table.insert(res, s2[2]) - end - end - end - return res +local function seqstr2tbl(seqstr) + local s = split(seqstr) + local res = {} + if (#s >= 1) then + for sk, sv in pairs(s) do + s2 = split(sv, '-') + if(#s2 == 2) then + table.insert(res, s2[1]) + table.insert(res, s2[2]) + end + end + end + return res end --- -- return sequence-string from table -function tbl2seqstr(seqtbl) - local res="" - if (istable(seqtbl)) then - for sk, sv in pairs(seqtbl) do - res=res..sv..((sk%2==0) and "," or "-") - end - if (string.sub(res, string.len(res))==",") then - res=string.sub(res, 1, string.len(res)-1) - end - end - return res +local function tbl2seqstr(seqtbl) + local res = "" + if (istable(seqtbl)) then + for sk, sv in pairs(seqtbl) do + res = res..sv..((sk%2==0) and "," or "-") + end + if (string.sub(res, string.len(res))== ",") then + res = string.sub(res, 1, string.len(res)-1) + end + end + return res end --- diff --git a/client/scripts/mifare_autopwn.lua b/client/scripts/mifare_autopwn.lua index 9bd149a55..738ca6950 100644 --- a/client/scripts/mifare_autopwn.lua +++ b/client/scripts/mifare_autopwn.lua @@ -12,8 +12,10 @@ This is a script which automates cracking and dumping mifare classic cards. It s place by the device. Arguments: - -d debug logging on - -h this help + -h this help + -d debug logging on + -k known key for Sector 0 , keytype A + Output files from this operation: .eml - emulator file @@ -73,12 +75,12 @@ local function nested(key,sak) if 0x18 == sak then --NXP MIFARE Classic 4k | Plus 4k | Ev1 4k typ = 4 elseif 0x08 == sak then -- NXP MIFARE CLASSIC 1k | Plus 2k | Ev1 1K - typ= 1 + typ = 1 elseif 0x09 == sak then -- NXP MIFARE Mini 0.3k typ = 0 - elseif 0x10 == sak then-- "NXP MIFARE Plus 2k" + elseif 0x10 == sak then-- "NXP MIFARE Plus 2k" typ = 2 - elseif 0x01 == sak then-- "NXP MIFARE TNP3xxx 1K" + elseif 0x01 == sak then-- "NXP MIFARE TNP3xxx 1K" typ = 1 else print("I don't know how many sectors there are on this type of card, defaulting to 16") @@ -87,22 +89,40 @@ local function nested(key,sak) core.console(cmd) end -local function dump(uid) +local function dump(uid, numsectors) dbg('dumping tag memory') + local typ = 1 + if 0x18 == sak then --NXP MIFARE Classic 4k | Plus 4k | Ev1 4k + typ = 4 + elseif 0x08 == sak then -- NXP MIFARE CLASSIC 1k | Plus 2k | Ev1 1K + typ = 1 + elseif 0x09 == sak then -- NXP MIFARE Mini 0.3k + typ = 0 + elseif 0x10 == sak then-- "NXP MIFARE Plus 2k" + typ = 2 + elseif 0x01 == sak then-- "NXP MIFARE TNP3xxx 1K" + typ = 1 + end + if utils.confirm('Do you wish to create a memory dump of tag?') then - core.console("hf mf dump") + local dumpfile = 'hf-mf-'..uid..'-data.bin' + + local dmp = ('hf mf dump %s f %s'):format(typ, dumpfile) + core.console(dmp) + -- Save the global args, those are *our* arguments local myargs = args -- Set the arguments for htmldump script - args =("-o %s.html"):format(uid) + args =('-i %s -o %s.html'):format(dumpfile, uid) -- call it - require('../scripts/htmldump') + require('htmldump') - args ="" -- dump to emulator - require('../scripts/dumptoemul') + args =('-i %s -o %s.eml'):format(dumpfile, uid) + require('dumptoemul') + -- Set back args. Not that it's used, just for the karma... args = myargs end @@ -177,9 +197,9 @@ local function main(args) print("Found valid key: "..key); end -- Use nested attack - nested(key,sak) + nested(key, sak) -- Dump info - dump(uid) + dump(uid, sak) if #key == 12 then exit = true end else diff --git a/client/scripts/ndef_dump.lua b/client/scripts/ndef_dump.lua index 3b27cac37..a0eda5b7f 100644 --- a/client/scripts/ndef_dump.lua +++ b/client/scripts/ndef_dump.lua @@ -24,13 +24,13 @@ local example = "script run xxx" local author = "Martin Holst Swende & Asper" --- -- PrintAndLog -function prlog(...) +local function prlog(...) -- TODO; replace this with a call to the proper PrintAndLog print(...) end --- -- This is only meant to be used when errors occur -function oops(err) +local function oops(err) prlog("ERROR: ",err) return nil,err end @@ -70,13 +70,13 @@ local utils = { --- -- Usage help -function help() +local function help() prlog(desc) prlog("Example usage") prlog(example) end -function debug(...) +local function debug(...) if DEBUG then prlog("debug:", ...) end @@ -158,7 +158,7 @@ end --- This function is a lua-implementation of -- cmdhf14a.c:waitCmd(uint8_t iSelect) -function waitCmd(iSelect) +local function waitCmd(iSelect) local response = core.WaitForResponseTimeout(cmds.CMD_ACK,1000) if response then local count,cmd,arg0,arg1,arg2 = bin.unpack('LLLL',response) diff --git a/client/scripts/read_pwd_mem.lua b/client/scripts/read_pwd_mem.lua index 772927c0c..a0688a639 100644 --- a/client/scripts/read_pwd_mem.lua +++ b/client/scripts/read_pwd_mem.lua @@ -21,6 +21,9 @@ Arguments: -o : memory offset, default is 0 -l : length in bytes, default is 256 -k : key length in bytes <4|6|8> , default is 4 + -m : print Mifare dictionary keys + -t : print t55xx dictionary passwords + -i : print iClass dictionary keys ]] example = [[ @@ -67,7 +70,7 @@ local function main(args) local keylength = 4 local usedkey = false - for o, a in getopt.getopt(args, 'ho:l:k:') do + for o, a in getopt.getopt(args, 'ho:l:k:mti') do -- help if o == "h" then return help() end @@ -80,6 +83,10 @@ local function main(args) -- keylength if o == "k" then keylength = tonumber(a); usedkey = true end + + if o == "m" then keylength =6; usedkey = true; offset = 0x3F000-0x4000; end + if o == "t" then keylength =4; usedkey = true; offset = 0x3F000-0x3000; end + if o == "i" then keylength =8; usedkey = true; offset = 0x3F000-0x5000; end end if length < 0 or length > 256 then diff --git a/client/scripts/remagic.lua b/client/scripts/remagic.lua index 5062d8cf4..10e25583a 100644 --- a/client/scripts/remagic.lua +++ b/client/scripts/remagic.lua @@ -72,6 +72,7 @@ local function sendCmds( cmds ) if cmds[i] then print ( cmds[i] ) core.console( cmds[i] ) + core.clearCommandBuffer() end end end diff --git a/client/scripts/tnp3clone.lua b/client/scripts/tnp3clone.lua index 2e1ee7019..b17cf2661 100644 --- a/client/scripts/tnp3clone.lua +++ b/client/scripts/tnp3clone.lua @@ -37,13 +37,12 @@ Arguments: 0020 - Swapforce ]] - -- This is only meant to be used when errors occur -function oops(err) +local function oops(err) print("ERROR: ",err) end -- Usage help -function help() +local function help() print(desc) print("Example usage") print(example) @@ -64,7 +63,7 @@ local function waitCmd() end local function readblock( blocknum, keyA ) - -- Read block 0 + -- Read block N cmd = Command:new{cmd = cmds.CMD_MIFARE_READBL, arg1 = blocknum, arg2 = 0, arg3 = 0, data = keyA} err = core.SendCommand(cmd:getBytes()) if err then return nil, err end @@ -72,8 +71,9 @@ local function readblock( blocknum, keyA ) if err then return nil, err end return block0 end + local function readmagicblock( blocknum ) - -- Read block 0 + -- Read block N local CSETBLOCK_SINGLE_OPERATION = 0x1F cmd = Command:new{cmd = cmds.CMD_MIFARE_CGETBLOCK, arg1 = CSETBLOCK_SINGLE_OPERATION, arg2 = 0, arg3 = blocknum} err = core.SendCommand(cmd:getBytes()) @@ -89,11 +89,13 @@ local function main(args) print( string.rep('--',20) ) local numBlocks = 64 - local cset = 'hf mf csetbl ' + local cset = 'hf mf csetbl ' local csetuid = 'hf mf csetuid ' local cget = 'hf mf cgetbl ' local empty = '00000000000000000000000000000000' - local AccAndKeyB = '7F078869000000000000' + local AccAndKeyB = '7F0F0869000000000000' + local atqa = '0F01' + local sak = '81' -- Defaults to Gusto local toytype = 'C201' local subtype = '0030' @@ -107,42 +109,43 @@ local function main(args) if o == "l" then return toys.List() end end - if #toytype ~= 4 then return oops('Wrong size - toytype. (4hex symbols)') end - if #subtype ~= 4 then return oops('Wrong size - subtype. (4hex symbols)') end + if #toytype ~= 4 then return oops('[!] Wrong size - toytype. (4hex symbols)') end + if #subtype ~= 4 then return oops('[!] Wrong size - subtype. (4hex symbols)') end -- look up type, find & validate types local item = toys.Find( toytype, subtype) if item then - print( (' Looking up input: Found %s - %s (%s)'):format(item[6],item[5], item[4]) ) + print( ('[+] Looking up input: Found %s - %s (%s)'):format(item[6],item[5], item[4]) ) else - print('Didn\'t find item type. If you are sure about it, report it in') + print('[-] Didn\'t find item type. If you are sure about it, post on forum') end --15,16 - --13-14 - + --13-14 -- find tag result, err = lib14a.read(false, true) - if not result then return oops(err) end + if not result then return oops(err) end -- load keys local akeys = pre.GetAll(result.uid) - local keyA = akeys:sub(1, 12 ) + local keyA = akeys:sub(1, 12 ) - local b0 = readblock(0,keyA) + local b0 = readblock(0, keyA) if not b0 then - print('failed reading block with factorydefault key. Trying chinese magic read.') + print('[-] failed reading block with factorydefault key. Trying chinese magic read.') b0, err = readmagicblock(0) if not b0 then - oops(err) - return oops('failed reading block with chinese magic command. quitting...') + oops('[!] '..err) + return oops('[!] failed reading block with chinese magic command. Quitting...') end end - - -- wipe card. - local cmd = (csetuid..'%s 0004 08 w'):format(result.uid) - core.console(cmd) + core.clearCommandBuffer() + -- wipe card. + local cmd = (csetuid..'%s %s %s w'):format(result.uid, atqa, sak) + core.console(cmd) + core.clearCommandBuffer() + local b1 = toytype..string.rep('00',10)..subtype local calc = utils.Crc16(b0..b1) @@ -150,6 +153,7 @@ local function main(args) local cmd = (cset..'1 %s%04x'):format( b1, calcEndian) core.console(cmd) + core.clearCommandBuffer() local pos, key for blockNo = 2, numBlocks-1, 1 do @@ -161,5 +165,10 @@ local function main(args) end end core.clearCommandBuffer() + + -- Set sector trailer S0, since it has different access rights + cmd = ('%s 3 %s0f0f0f69000000000000'):format(cset, keyA) + core.console(cmd) + core.clearCommandBuffer() end -main(args) \ No newline at end of file +main(args) diff --git a/client/tinycbor/cborparser_dup_string.c b/client/tinycbor/cborparser_dup_string.c index 061c5ac77..202cd2022 100644 --- a/client/tinycbor/cborparser_dup_string.c +++ b/client/tinycbor/cborparser_dup_string.c @@ -105,7 +105,7 @@ CborError _cbor_value_dup_string(const CborValue *value, void **buffer, size_t * return err; ++*buflen; - *buffer = malloc(*buflen); + *buffer = calloc(*buflen, sizeof(uint8_t)); if (!*buffer) { /* out of memory */ return CborErrorOutOfMemory; diff --git a/client/tinycbor/cbortojson.c b/client/tinycbor/cbortojson.c index 5a1a2e5dc..34b900bab 100644 --- a/client/tinycbor/cbortojson.c +++ b/client/tinycbor/cbortojson.c @@ -178,7 +178,7 @@ static CborError dump_bytestring_base16(char **result, CborValue *it) return err; /* a Base16 (hex) output is twice as big as our buffer */ - buffer = (uint8_t *)malloc(n * 2 + 1); + buffer = (uint8_t *)calloc(n * 2 + 1, sizeof(uint8_t)); *result = (char *)buffer; /* let cbor_value_copy_byte_string know we have an extra byte for the terminating NUL */ @@ -204,7 +204,7 @@ static CborError generic_dump_base64(char **result, CborValue *it, const char al /* a Base64 output (untruncated) has 4 bytes for every 3 in the input */ size_t len = (n + 5) / 3 * 4; - out = buffer = (uint8_t *)malloc(len + 1); + out = buffer = (uint8_t *)calloc(len + 1, sizeof(uint8_t)); *result = (char *)buffer; /* we read our byte string at the tail end of the buffer diff --git a/client/tinycbor/open_memstream.c b/client/tinycbor/open_memstream.c index 18f3de8b1..f618db8ae 100644 --- a/client/tinycbor/open_memstream.c +++ b/client/tinycbor/open_memstream.c @@ -90,7 +90,7 @@ static int close_buffer(void *cookie) FILE *open_memstream(char **bufptr, size_t *lenptr) { - struct Buffer *b = (struct Buffer *)malloc(sizeof(struct Buffer)); + struct Buffer *b = (struct Buffer *)calloc(sizeof(struct Buffer), sizeof(uint8_t)); if (b == NULL) return NULL; b->alloc = 0; diff --git a/client/ui.c b/client/ui.c index a0151a8db..71603fed6 100644 --- a/client/ui.c +++ b/client/ui.c @@ -196,7 +196,7 @@ void SetFlushAfterWrite(bool value) { int i,j; - int * output = (int* ) malloc(sizeof(int) * len); + int * output = (int* ) calloc(sizeof(int) * len, sizeof(uint8_t)); if ( !output ) return; // clear mem diff --git a/client/util.c b/client/util.c index b22258d44..cea42f338 100644 --- a/client/util.c +++ b/client/util.c @@ -280,7 +280,7 @@ void sprint_bin_break_ex(uint8_t *src, size_t srclen, char *dest , uint8_t break printf("(sprint_bin_break) rowlen %d\n", rowlen); // 3072 + end of line characters if broken at 8 bits - dest = (char *)malloc(MAX_BIN_BREAK_LENGTH); + dest = (char *)calloc(MAX_BIN_BREAK_LENGTH, sizeof(uint8_t)); if (dest == NULL) return; //clear memory @@ -884,8 +884,8 @@ extern void strcreplace(char *buf, size_t len, char from, char to) { } extern char *strmcopy(char *buf) { - char* str = NULL; - if ((str = (char*) malloc(strlen(buf) + 1)) != NULL) { + char* str = (char*) calloc(strlen(buf) + 1, sizeof(uint8_t)); + if (str != NULL) { memset(str, 0, strlen(buf) + 1); strcpy(str, buf); } diff --git a/client/util.h b/client/util.h index c9f13870d..e10f06497 100644 --- a/client/util.h +++ b/client/util.h @@ -178,6 +178,14 @@ } #endif +#ifndef DropFieldEx +#define DropFieldEx(x) { \ + if ( (x) == ECC_CONTACTLESS) { \ + DropField(); \ + } \ +} +#endif + extern uint8_t g_debugMode; extern int ukbhit(void); diff --git a/common/crapto1/crapto1.c b/common/crapto1/crapto1.c index 8dc8f26c8..af1ed8167 100644 --- a/common/crapto1/crapto1.c +++ b/common/crapto1/crapto1.c @@ -405,7 +405,7 @@ int nonce_distance(uint32_t from, uint32_t to) { uint16_t x, i; if(!dist) { - dist = malloc(2 << 16); + dist = calloc(2 << 16, sizeof(uint8_t)); if(!dist) return -1; for (x = i = 1; i; ++i) { @@ -443,7 +443,7 @@ static uint32_t fastfwd[2][8] = { */ uint32_t *lfsr_prefix_ks(uint8_t ks[8], int isodd) { - uint32_t *candidates = malloc(4 << 10); + uint32_t *candidates = calloc(4 << 10, sizeof(uint8_t)); if (!candidates) return 0; uint32_t c, entry; diff --git a/common/iso15693tools.h b/common/iso15693tools.h index 053ca56ca..70382ce04 100644 --- a/common/iso15693tools.h +++ b/common/iso15693tools.h @@ -1,5 +1,11 @@ -// ISO15693 commons -// Adrian Dabrowski 2010 and others, GPLv2 +//----------------------------------------------------------------------------- +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// ISO15693 other commons +//----------------------------------------------------------------------------- +// Adrian Dabrowski 2010 and otherss // Christian Herrmann 2018 #ifndef ISO15693_H__ diff --git a/common/protocols.h b/common/protocols.h index 9696c73e0..3c2e79a8d 100644 --- a/common/protocols.h +++ b/common/protocols.h @@ -302,10 +302,10 @@ ISO 7816-4 Basic interindustry commands. For command APDU's. #define ISO7816_VERIFY 0x20 #define ISO7816_INTERNAL_AUTHENTICATION 0x88 #define ISO7816_EXTERNAL_AUTHENTICATION 0x82 -#define ISO7816_GET_CHALLENGE 0xB4 +#define ISO7816_GET_CHALLENGE 0x84 #define ISO7816_MANAGE_CHANNEL 0x70 -#define ISO7816_GETSTATUS 0xC0 +#define ISO7816_GET_RESPONSE 0xC0 // ISO7816-4 For response APDU's #define ISO7816_OK 0x9000 // 6x xx = ERROR diff --git a/common/radixsort.c b/common/radixsort.c index 91495316c..981c19191 100644 --- a/common/radixsort.c +++ b/common/radixsort.c @@ -3,7 +3,7 @@ uint64_t * radixSort(uint64_t * array, uint32_t size) { rscounts_t counts; memset(&counts, 0, 256 * 8 * sizeof(uint32_t)); - uint64_t * cpy = (uint64_t *)malloc(size * sizeof(uint64_t)); + uint64_t * cpy = (uint64_t *)calloc(size * sizeof(uint64_t), sizeof(uint8_t)); uint32_t o8=0, o7=0, o6=0, o5=0, o4=0, o3=0, o2=0, o1=0; uint32_t t8, t7, t6, t5, t4, t3, t2, t1; uint32_t x; diff --git a/include/mifare.h b/include/mifare.h index cda7cfe9d..14c0e7e27 100644 --- a/include/mifare.h +++ b/include/mifare.h @@ -35,7 +35,8 @@ typedef enum ISO14A_COMMAND { ISO14A_SET_TIMEOUT = (1 << 6), ISO14A_NO_SELECT = (1 << 7), ISO14A_TOPAZMODE = (1 << 8), - ISO14A_NO_RATS = (1 << 9) + ISO14A_NO_RATS = (1 << 9), + ISO14A_SEND_CHAINING = (1 << 10) } iso14a_command_t; typedef struct { diff --git a/include/usb_cmd.h b/include/usb_cmd.h index 44d031334..a54b27e0f 100644 --- a/include/usb_cmd.h +++ b/include/usb_cmd.h @@ -140,6 +140,8 @@ typedef struct{ #define CMD_COTAG 0x0225 #define CMD_SET_LF_T55XX_CONFIG 0x0226 +#define CMD_T55XX_CHKPWDS 0x0230 + /* CMD_SET_ADC_MUX: ext1 is 0 for lopkd, 1 for loraw, 2 for hipkd, 3 for hiraw */ // For the 13.56 MHz tags diff --git a/tools/Makefile b/tools/Makefile index 0a6e4430e..b72503158 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -8,4 +8,12 @@ get_crapto1: get_nonce_bf: # git clone https://github.com/J-Run/mf_key_brute.git mf_key_brute - git clone https://github.com/iceman1001/mf_nonce_brute mf_nonce_brute \ No newline at end of file + git clone https://github.com/iceman1001/mf_nonce_brute mf_nonce_brute + +get_xorsearch: + mkdir xorsearch + wget -N https://didierstevens.com/files/software/XORSearch_V1_11_2.zip +# Mingw +# unzzip-big XORSearch_V1_11_2.zip +# linux +# gunzip XORSearch_V1_11_2.zip \ No newline at end of file diff --git a/tools/mkversion.pl b/tools/mkversion.pl index 1acca6efa..674c44177 100644 --- a/tools/mkversion.pl +++ b/tools/mkversion.pl @@ -28,7 +28,7 @@ my $clean = 2; # fatal: No names found, cannot describe anything. ## # anyway forcing any kind of shell is at least useless, at worst fatal. -my $commandGIT = "env -S which git"; +my $commandGIT = "env which git"; if ( defined($commandGIT) ) { diff --git a/uart/uart_posix.c b/uart/uart_posix.c index d857729d6..093aaf363 100644 --- a/uart/uart_posix.c +++ b/uart/uart_posix.c @@ -68,14 +68,14 @@ typedef struct { } serial_port_unix; // Set time-out on 30 miliseconds -const struct timeval timeout = { +struct timeval timeout = { .tv_sec = 0, // 0 second - .tv_usec = 300000 // 300 000 micro seconds + .tv_usec = 30000 // 30000 micro seconds }; serial_port uart_open(const char* pcPortName) { - serial_port_unix* sp = malloc(sizeof(serial_port_unix)); + serial_port_unix* sp = calloc(sizeof(serial_port_unix), sizeof(uint8_t)); if (sp == 0) return INVALID_SERIAL_PORT; if (memcmp(pcPortName, "tcp:", 4) == 0) { @@ -89,6 +89,10 @@ serial_port uart_open(const char* pcPortName) char *colon = strrchr(addrstr, ':'); char *portstr; + + // Set time-out to 300 miliseconds only for TCP port + timeout.tv_usec = 300000; + if (colon) { portstr = colon + 1; *colon = '\0'; diff --git a/uart/uart_win32.c b/uart/uart_win32.c index 11c90f15f..438f586c8 100644 --- a/uart/uart_win32.c +++ b/uart/uart_win32.c @@ -50,7 +50,7 @@ typedef struct { serial_port uart_open(const char* pcPortName) { char acPortName[255]; - serial_port_windows* sp = malloc(sizeof(serial_port_windows)); + serial_port_windows* sp = calloc(sizeof(serial_port_windows), sizeof(uint8_t)); if (sp == 0) { printf("[!] UART failed to allocate memory\n");