Merge branch 'master' of github.com:merlokk/proxmark3i into emv_vsdc

This commit is contained in:
merlokk 2019-02-19 18:34:52 +02:00
commit bebfcab7b9
84 changed files with 3694 additions and 923 deletions

View file

@ -1,6 +1,9 @@
--- ---
name: Bug report name: Bug report
about: Create a report to help us improve about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
--- ---

View file

@ -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.

View file

@ -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... 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] ## [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 'lf pcf7931' - improved read code (@sguerrini97)
- Change 'hf felica list' - started with some FeliCa annotations (@iceman) - Change 'hf felica list' - started with some FeliCa annotations (@iceman)
- Fix 'hf tune' - now works as expected (@iceman) - Fix 'hf tune' - now works as expected (@iceman)

View file

@ -5,6 +5,33 @@ Proxmark3 RDV40 dedicated repo, based on iceman fork
## Notice ## 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. 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 ## Coverity Scan Config & Run
Download the Coverity Scan Self-buld and install it. Download the Coverity Scan Self-buld and install it.
You will need to configure ARM-NON-EABI- Compiler for it to use: 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. Give us a hint, and we'll see if we can't merge in the stuff you have.
## PM3 GUI ## PM3 GUI
The official PM3-GUI from Gaucho will not work. The official PM3-GUI from Gaucho will not work.
The new universial GUI will work. The new universial GUI will work. [Proxmark3 Univerisal GUI](https://github.com/burma69/PM3UniversalGUI)
## Development ## Development
This fork now compiles just fine on This fork now compiles just fine on
- Windows/mingw environment with Qt5.6.1 & GCC 4.8 - Windows/mingw environment with Qt5.6.1 & GCC 4.8
- Ubuntu 1404, 1510, 1604, 1804 - Ubuntu 1404, 1510, 1604, 1804
- Mac OS X / Homebrew - Mac OS X / Homebrew
- ParrotOS
- WSL (Windows subsystem linux) on Windows 10
- Docker container - Docker container
## KALI and ARCHLINUX users ## KALI and ARCHLINUX users
Kali and ArchLinux users usually must kill their modem manager in order for the proxmark3 to enumerate properly. 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 ## 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 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 https://github.com/RfidResearchGroup/proxmark3/blob/master/install.sh
- Run - 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 - Clone fork
`git clone https://github.com/RfidResearchGroup/proxmark3.git` `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 ## Setup and build for ArchLinux
- Run - 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` `yaourt -S termcap`
- Remove modemmanager - Remove modemmanager
@ -224,7 +260,7 @@ If all went well you should get some information about the firmware and memory u
> >
> pm3 --> > pm3 -->
### run the following commands ### Run the following commands
pm3 --> hw status pm3 --> hw status
pm3 --> hw version pm3 --> hw version
pm3 --> hw tune pm3 --> hw tune
@ -240,6 +276,46 @@ You are now ready to use your newly upgraded proxmark3 device. Many commands us
pm3 --> quit 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 ## the end
`iceman at host iuse.se` `iceman at host iuse.se`

View file

@ -21,7 +21,7 @@ APP_CFLAGS = -DWITH_CRC \
-DWITH_ISO14443a \ -DWITH_ISO14443a \
-DWITH_ICLASS \ -DWITH_ICLASS \
-DWITH_FELICA \ -DWITH_FELICA \
-DWITH_FLASH \ -DWITH_FLASH \
-DWITH_SMARTCARD \ -DWITH_SMARTCARD \
-DWITH_FPC \ -DWITH_FPC \
-DWITH_HFSNOOP \ -DWITH_HFSNOOP \
@ -191,7 +191,7 @@ $(OBJDIR)/fpga_all.bit.z: $(FPGA_BITSTREAMS) $(FPGA_COMPRESSOR)
$(FPGA_COMPRESSOR) $(filter %.bit,$^) $@ $(FPGA_COMPRESSOR) $(filter %.bit,$^) $@
$(FPGA_COMPRESSOR): $(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) $(OBJDIR)/fullimage.stage1.elf: $(VERSIONOBJ) $(OBJDIR)/fpga_all.o $(THUMBOBJ) $(ARMOBJ)
$(CC) $(LDFLAGS) -Wl,-T,ldscript,-Map,$(patsubst %.elf,%.map,$@) -o $@ $^ $(LIBS) $(CC) $(LDFLAGS) -Wl,-T,ldscript,-Map,$(patsubst %.elf,%.map,$@) -o $@ $^ $(LIBS)

View file

@ -271,6 +271,11 @@ void RAMFUNC SniffAndStore(uint8_t param) {
uint16_t writelen = Flash_WriteData(0, total_data, memoffset + 4 * auth_attempts); 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 (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); SpinDelay(100);
// Reset the SPI Baudrate to the default value (24MHz) // Reset the SPI Baudrate to the default value (24MHz)

View file

@ -724,6 +724,9 @@ void UsbPacketReceived(uint8_t *packet, int len) {
case CMD_T55XX_RESET_READ: case CMD_T55XX_RESET_READ:
T55xxResetRead(); T55xxResetRead();
break; break;
case CMD_T55XX_CHKPWDS:
T55xx_ChkPwds();
break;
case CMD_PCF7931_READ: case CMD_PCF7931_READ:
ReadPCF7931(); ReadPCF7931();
break; break;

View file

@ -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 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 T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd);
void T55xxWakeUp(uint32_t Pwd); void T55xxWakeUp(uint32_t Pwd);
void T55xx_ChkPwds(void);
void TurnReadLFOn(uint32_t delay); void TurnReadLFOn(uint32_t delay);
void EM4xReadWord(uint8_t addr, uint32_t pwd, uint8_t usepwd); void EM4xReadWord(uint8_t addr, uint32_t pwd, uint8_t usepwd);
void EM4xWriteWord(uint32_t flag, uint32_t data, uint32_t pwd); void EM4xWriteWord(uint32_t flag, uint32_t data, uint32_t pwd);

View file

@ -108,7 +108,7 @@ int EPA_APDU(uint8_t *apdu, size_t length, uint8_t *response)
switch(iso_type) switch(iso_type)
{ {
case 'a': case 'a':
return iso14_apdu(apdu, (uint16_t) length, response, NULL); return iso14_apdu(apdu, (uint16_t) length, false, response, NULL);
break; break;
case 'b': case 'b':
return iso14443b_apdu(apdu, length, response); return iso14443b_apdu(apdu, length, response);

View file

@ -2219,13 +2219,16 @@ b8 b7 b6 b5 b4 b3 b2 b1
b5,b6 = 00 - DESELECT b5,b6 = 00 - DESELECT
11 - WTX 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 parity[MAX_PARITY_SIZE] = {0x00};
uint8_t real_cmd[cmd_len + 4]; uint8_t real_cmd[cmd_len + 4];
if (cmd_len) { if (cmd_len) {
// ISO 14443 APDU frame: PCB [CID] [NAD] APDU CRC PCB=0x02 // ISO 14443 APDU frame: PCB [CID] [NAD] APDU CRC PCB=0x02
real_cmd[0] = 0x02; // bnr,nad,cid,chn=0; i-block(0x00) 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 // put block number into the PCB
real_cmd[0] |= iso14_pcb_blocknum; real_cmd[0] |= iso14_pcb_blocknum;
memcpy(real_cmd + 1, cmd, cmd_len); 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 return 0; //DATA LINK ERROR
} else{ } else{
// S-Block WTX // S-Block WTX
while((data_bytes[0] & 0xF2) == 0xF2) { while(len && ((data_bytes[0] & 0xF2) == 0xF2)) {
uint32_t save_iso14a_timeout = iso14a_get_timeout(); uint32_t save_iso14a_timeout = iso14a_get_timeout();
// temporarily increase timeout // temporarily increase timeout
iso14a_set_timeout( MAX((data_bytes[1] & 0x3f) * save_iso14a_timeout, MAX_ISO14A_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); iso14a_set_timeout(save_iso14a_timeout);
} }
// if we received an I- or R(ACK)-Block with a block number equal to the // if we received an I- or R(ACK)-Block with a block number equal to the
// current block number, toggle the current block number // current block number, toggle the current block number
if (len >= 3 // PCB+CRC = 3 bytes if (len >= 3 // PCB+CRC = 3 bytes
&& ((data_bytes[0] & 0xC0) == 0 // I-Block && ((data_bytes[0] & 0xC0) == 0 // I-Block
|| (data_bytes[0] & 0xD0) == 0x80) // R-Block with ACK bit set to 0 || (data_bytes[0] & 0xD0) == 0x80) // R-Block with ACK bit set to 0
&& (data_bytes[0] & 0x01) == iso14_pcb_blocknum) // equal block numbers && (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 we received I-block with chaining we need to send ACK and receive another block of data
if (res) if (res)
*res = data_bytes[0]; *res = data_bytes[0];
// crc check // 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; return -1;
} }
} }
// cut frame byte if (len) {
len -= 1; // cut frame byte
// memmove(data_bytes, data_bytes + 1, len); len -= 1;
for (int i = 0; i < len; i++) // memmove(data_bytes, data_bytes + 1, len);
data_bytes[i] = data_bytes[i + 1]; for (int i = 0; i < len; i++)
data_bytes[i] = data_bytes[i + 1];
}
return len; return len;
} }
@ -2338,7 +2343,7 @@ void ReaderIso14443a(UsbCommand *c) {
if ((param & ISO14A_APDU)) { if ((param & ISO14A_APDU)) {
uint8_t res; 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)); cmd_send(CMD_ACK, arg0, res, 0, buf, sizeof(buf));
} }

View file

@ -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 int ReaderReceive(uint8_t *receivedAnswer, uint8_t *par);
extern void iso14443a_setup(uint8_t fpga_minor_mode); 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_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 int iso14443a_fast_select_card(uint8_t *uid_ptr, uint8_t num_cascades);
extern void iso14a_set_trigger(bool enable); extern void iso14a_set_trigger(bool enable);

View file

@ -61,7 +61,7 @@ static inline uint8_t rx_byte_from_fpga() {
WDT_HIT(); WDT_HIT();
// wait for byte be become available in rx holding register // 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; 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: // To reduce CPU time the amplitude is approximated by using linear functions:
// am = MAX(ABS(i),ABS(q)) + 1/2*MIN(ABS(i),ABSq)) // 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. // on a i/q pair from two subsequent correlations, but does not matter.
static inline int32_t sample_power() { static inline int32_t sample_power() {
int32_t q = (int8_t)rx_byte_from_fpga(); q = ABS(q); 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() { static inline bool rx_bit() {
int32_t power; int32_t power;
for(size_t i = 0; i<5; ++i) { for (size_t i = 0; i<5; ++i) {
power = sample_power(); power = sample_power();
} }
@ -120,12 +120,12 @@ static inline void tx_bit(bool bit) {
// insert pause // insert pause
LOW(GPIO_SSC_DOUT); LOW(GPIO_SSC_DOUT);
last_frame_end += RWD_TIME_PAUSE; last_frame_end += RWD_TIME_PAUSE;
while(GET_TICKS < last_frame_end) { }; while (GET_TICKS < last_frame_end) { };
HIGH(GPIO_SSC_DOUT); HIGH(GPIO_SSC_DOUT);
// return to high, wait for bit periode to end // return to high, wait for bit periode to end
last_frame_end += (bit ? RWD_TIME_1 : RWD_TIME_0) - RWD_TIME_PAUSE; 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 // wait for next tx timeslot
last_frame_end += RWD_FRAME_WAIT; last_frame_end += RWD_FRAME_WAIT;
while(GET_TICKS < last_frame_end) { }; while (GET_TICKS < last_frame_end) { };
// backup ts for trace log // backup ts for trace log
uint32_t last_frame_start = last_frame_end; uint32_t last_frame_start = last_frame_end;
// transmit frame, MSB first // 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; bool bit = (frame >> i) & 0x01;
tx_bit(bit ^ legic_prng_get_bit()); tx_bit(bit ^ legic_prng_get_bit());
legic_prng_forward(1); 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 // add pause to mark end of the frame
LOW(GPIO_SSC_DOUT); LOW(GPIO_SSC_DOUT);
last_frame_end += RWD_TIME_PAUSE; last_frame_end += RWD_TIME_PAUSE;
while(GET_TICKS < last_frame_end) { }; while (GET_TICKS < last_frame_end) { };
HIGH(GPIO_SSC_DOUT); HIGH(GPIO_SSC_DOUT);
// log // log
@ -173,19 +173,19 @@ static uint32_t rx_frame(uint8_t len) {
// hold sampling until card is expected to respond // hold sampling until card is expected to respond
last_frame_end += TAG_FRAME_WAIT; last_frame_end += TAG_FRAME_WAIT;
while(GET_TICKS < last_frame_end) { }; while (GET_TICKS < last_frame_end) { };
// backup ts for trace log // backup ts for trace log
uint32_t last_frame_start = last_frame_end; uint32_t last_frame_start = last_frame_end;
uint32_t frame = 0; 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; frame |= (rx_bit() ^ legic_prng_get_bit()) << i;
legic_prng_forward(1); legic_prng_forward(1);
// rx_bit runs only 95us, resync to TAG_BIT_PERIOD // rx_bit runs only 95us, resync to TAG_BIT_PERIOD
last_frame_end += TAG_BIT_PERIOD; last_frame_end += TAG_BIT_PERIOD;
while(GET_TICKS < last_frame_end) { }; while (GET_TICKS < last_frame_end) { };
} }
// log // log
@ -203,23 +203,23 @@ static bool rx_ack() {
// hold sampling until card is expected to respond // hold sampling until card is expected to respond
last_frame_end += TAG_FRAME_WAIT; last_frame_end += TAG_FRAME_WAIT;
while(GET_TICKS < last_frame_end) { }; while (GET_TICKS < last_frame_end) { };
// backup ts for trace log // backup ts for trace log
uint32_t last_frame_start = last_frame_end; uint32_t last_frame_start = last_frame_end;
uint32_t ack = 0; 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 // sample bit
ack = rx_bit(); ack = rx_bit();
legic_prng_forward(1); legic_prng_forward(1);
// rx_bit runs only 95us, resync to TAG_BIT_PERIOD // rx_bit runs only 95us, resync to TAG_BIT_PERIOD
last_frame_end += 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 // check if it was an ACK
if(ack) { if (ack) {
break; 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. // reserve a cardmem, meaning we can use the tracelog function in bigbuff easier.
legic_mem = BigBuf_get_EM_addr(); legic_mem = BigBuf_get_EM_addr();
if(legic_mem) { if (legic_mem) {
memset(legic_mem, 0x00, LEGIC_CARD_MEMSIZE); 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. // Switch on carrier and let the card charge for 5ms.
last_frame_end += 7500; last_frame_end += 7500;
while(GET_TICKS < last_frame_end) { }; while (GET_TICKS < last_frame_end) { };
legic_prng_init(0); legic_prng_init(0);
tx_frame(iv, 7); 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 // check received against calculated crc
uint8_t calc_crc = calc_crc4(cmd, cmd_sz, byte); 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); Dbprintf("!!! crc mismatch: %x != %x !!!", calc_crc, crc);
return -1; return -1;
} }
@ -399,15 +399,15 @@ void LegicRfInfo(void) {
// establish shared secret and detect card type // establish shared secret and detect card type
uint8_t card_type = setup_phase(0x01); 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); cmd_send(CMD_ACK, 0, 0, 0, 0, 0);
goto OUT; goto OUT;
} }
// read UID // 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); int16_t byte = read_byte(i, card.cmdsize);
if(byte == -1) { if (byte == -1) {
cmd_send(CMD_ACK, 0, 0, 0, 0, 0); cmd_send(CMD_ACK, 0, 0, 0, 0, 0);
goto OUT; goto OUT;
} }
@ -417,7 +417,7 @@ void LegicRfInfo(void) {
// read MCC and check against UID // read MCC and check against UID
int16_t mcc = read_byte(4, card.cmdsize); int16_t mcc = read_byte(4, card.cmdsize);
int16_t calc_mcc = CRC8Legic(card.uid, 4);; 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); cmd_send(CMD_ACK, 0, 0, 0, 0, 0);
goto OUT; goto OUT;
} }
@ -436,19 +436,19 @@ void LegicRfReader(uint16_t offset, uint16_t len, uint8_t iv) {
// establish shared secret and detect card type // establish shared secret and detect card type
uint8_t card_type = setup_phase(iv); 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); cmd_send(CMD_ACK, 0, 0, 0, 0, 0);
goto OUT; goto OUT;
} }
// do not read beyond card memory // do not read beyond card memory
if(len + offset > card.cardsize) { if (len + offset > card.cardsize) {
len = card.cardsize - offset; 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); int16_t byte = read_byte(offset + i, card.cmdsize);
if(byte == -1) { if (byte == -1) {
cmd_send(CMD_ACK, 0, 0, 0, 0, 0); cmd_send(CMD_ACK, 0, 0, 0, 0, 0);
goto OUT; goto OUT;
} }
@ -468,26 +468,26 @@ void LegicRfWriter(uint16_t offset, uint16_t len, uint8_t iv, uint8_t *data) {
init_reader(false); init_reader(false);
// uid is not writeable // uid is not writeable
if(offset <= WRITE_LOWERLIMIT) { if (offset <= WRITE_LOWERLIMIT) {
cmd_send(CMD_ACK, 0, 0, 0, 0, 0); cmd_send(CMD_ACK, 0, 0, 0, 0, 0);
goto OUT; goto OUT;
} }
// establish shared secret and detect card type // establish shared secret and detect card type
uint8_t card_type = setup_phase(iv); 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); cmd_send(CMD_ACK, 0, 0, 0, 0, 0);
goto OUT; goto OUT;
} }
// do not write beyond card memory // do not write beyond card memory
if(len + offset > card.cardsize) { if (len + offset > card.cardsize) {
len = card.cardsize - offset; len = card.cardsize - offset;
} }
// write in reverse order, only then is DCF (decremental field) writable // write in reverse order, only then is DCF (decremental field) writable
while(len-- > 0 && !BUTTON_PRESS()) { while (len-- > 0 && !BUTTON_PRESS()) {
if(!write_byte(len + offset, data[len], card.addrsize)) { if (!write_byte(len + offset, data[len], card.addrsize)) {
Dbprintf("operation failed | %02X | %02X | %02X", len + offset, len, data[len]); Dbprintf("operation failed | %02X | %02X | %02X", len + offset, len, data[len]);
cmd_send(CMD_ACK, 0, 0, 0, 0, 0); cmd_send(CMD_ACK, 0, 0, 0, 0, 0);
goto OUT; goto OUT;

View file

@ -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_PAUSE 4 /* 18.9us */
#define RWD_TIME_1 21 /* RWD_TIME_PAUSE 18.9us off + 80.2us on = 99.1us */ #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_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_MIN_FRAME_LEN 6 /* Shortest frame is 6 bits */
#define RWD_MAX_FRAME_LEN 23 /* Longest frame is 23 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 // Returns true if a pulse/pause is received within timeout
static inline bool wait_for(bool value, const uint32_t timeout) { static inline bool wait_for(bool value, const uint32_t timeout) {
while((bool)(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_DIN) != value) { while ((bool)(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_DIN) != value) {
if(GetCountSspClk() > timeout) { if (GetCountSspClk() > timeout) {
return false; return false;
} }
} }
@ -81,12 +81,12 @@ static inline int8_t rx_bit() {
uint32_t bit_start = last_frame_end; uint32_t bit_start = last_frame_end;
// wait for pause to 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; return -1;
} }
// wait for next pause // 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; return -1;
} }
@ -94,7 +94,7 @@ static inline int8_t rx_bit() {
last_frame_end = GetCountSspClk(); last_frame_end = GetCountSspClk();
// check for code violation (bit to short) // 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; return -1;
} }
@ -122,7 +122,7 @@ static inline int8_t rx_bit() {
static inline void tx_bit(bool bit) { static inline void tx_bit(bool bit) {
LED_C_ON(); LED_C_ON();
if(bit) { if (bit) {
// modulate subcarrier // modulate subcarrier
HIGH(GPIO_SSC_DOUT); HIGH(GPIO_SSC_DOUT);
} else { } else {
@ -132,7 +132,7 @@ static inline void tx_bit(bool bit) {
// wait for tx timeslot to end // wait for tx timeslot to end
last_frame_end += TAG_BIT_PERIOD; last_frame_end += TAG_BIT_PERIOD;
while(GetCountSspClk() < last_frame_end) { }; while (GetCountSspClk() < last_frame_end) { };
LED_C_OFF(); LED_C_OFF();
} }
@ -150,13 +150,13 @@ static void tx_frame(uint32_t frame, uint8_t len) {
// wait for next tx timeslot // wait for next tx timeslot
last_frame_end += TAG_FRAME_WAIT; last_frame_end += TAG_FRAME_WAIT;
legic_prng_forward(TAG_FRAME_WAIT/TAG_BIT_PERIOD - 1); 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 // backup ts for trace log
uint32_t last_frame_start = last_frame_end; uint32_t last_frame_start = last_frame_end;
// transmit frame, MSB first // 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; bool bit = (frame >> i) & 0x01;
tx_bit(bit ^ legic_prng_get_bit()); tx_bit(bit ^ legic_prng_get_bit());
legic_prng_forward(1); legic_prng_forward(1);
@ -174,7 +174,7 @@ static void tx_ack() {
// wait for ack timeslot // wait for ack timeslot
last_frame_end += TAG_ACK_WAIT; last_frame_end += TAG_ACK_WAIT;
legic_prng_forward(TAG_ACK_WAIT/TAG_BIT_PERIOD - 1); 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 // backup ts for trace log
uint32_t last_frame_start = last_frame_end; uint32_t last_frame_start = last_frame_end;
@ -206,19 +206,19 @@ static int32_t rx_frame(uint8_t *len) {
last_frame_end -= 2; last_frame_end -= 2;
// wait for first pause (start of frame) // 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 // increment prng every TAG_BIT_PERIOD
last_frame_end += TAG_BIT_PERIOD; last_frame_end += TAG_BIT_PERIOD;
legic_prng_forward(1); legic_prng_forward(1);
// if start of frame was received exit delay loop // 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(); last_frame_end = GetCountSspClk();
break; break;
} }
// check for code violation // check for code violation
if(i > RWD_CMD_TIMEOUT) { if (i > RWD_CMD_TIMEOUT) {
return -1; return -1;
} }
} }
@ -227,19 +227,19 @@ static int32_t rx_frame(uint8_t *len) {
uint32_t last_frame_start = last_frame_end; uint32_t last_frame_start = last_frame_end;
// receive frame // receive frame
for(*len = 0; true; ++(*len)) { for (*len = 0; true; ++(*len)) {
// receive next bit // receive next bit
LED_B_ON(); LED_B_ON();
int8_t bit = rx_bit(); int8_t bit = rx_bit();
LED_B_OFF(); LED_B_OFF();
// check for code violation and to short / long frame // 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; return -1;
} }
// check for code violation caused by end of frame // check for code violation caused by end of frame
if(bit < 0) { if (bit < 0) {
break; break;
} }
@ -256,7 +256,6 @@ static int32_t rx_frame(uint8_t *len) {
// log // log
uint8_t cmdbytes[] = {*len, BYTEx(frame, 0), BYTEx(frame, 1), BYTEx(frame, 2)}; 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); LogTrace(cmdbytes, sizeof(cmdbytes), last_frame_start, last_frame_end, NULL, true);
return frame; 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) { static int32_t init_card(uint8_t cardtype, legic_card_select_t *p_card) {
p_card->tagtype = cardtype; p_card->tagtype = cardtype;
switch(p_card->tagtype) { switch (p_card->tagtype) {
case 0: case 0:
p_card->cmdsize = 6; p_card->cmdsize = 6;
p_card->addrsize = 5; p_card->addrsize = 5;
@ -338,7 +337,7 @@ static int32_t setup_phase(legic_card_select_t *p_card) {
// wait for iv // wait for iv
int32_t iv = rx_frame(&len); int32_t iv = rx_frame(&len);
if((len != 7) || (iv < 0)) { if ((len != 7) || (iv < 0)) {
return -1; return -1;
} }
@ -346,7 +345,7 @@ static int32_t setup_phase(legic_card_select_t *p_card) {
legic_prng_init(iv); legic_prng_init(iv);
// reply with card type // reply with card type
switch(p_card->tagtype) { switch (p_card->tagtype) {
case 0: case 0:
tx_frame(0x0D, 6); tx_frame(0x0D, 6);
break; break;
@ -360,12 +359,12 @@ static int32_t setup_phase(legic_card_select_t *p_card) {
// wait for ack // wait for ack
int32_t ack = rx_frame(&len); int32_t ack = rx_frame(&len);
if((len != 6) || (ack < 0)) { if ((len != 6) || (ack < 0)) {
return -1; return -1;
} }
// validate data // validate data
switch(p_card->tagtype) { switch (p_card->tagtype) {
case 0: case 0:
if(ack != 0x19) return -1; if(ack != 0x19) return -1;
break; break;
@ -399,12 +398,12 @@ static int32_t connected_phase(legic_card_select_t *p_card) {
// wait for command // wait for command
int32_t cmd = rx_frame(&len); int32_t cmd = rx_frame(&len);
if(cmd < 0) { if (cmd < 0) {
return -1; return -1;
} }
// check if command is LEGIC_READ // check if command is LEGIC_READ
if(len == p_card->cmdsize) { if (len == p_card->cmdsize) {
// prepare data // prepare data
uint8_t byte = legic_mem[cmd >> 1]; uint8_t byte = legic_mem[cmd >> 1];
uint8_t crc = calc_crc4(cmd, p_card->cmdsize, byte); 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 // check if command is LEGIC_WRITE
if(len == p_card->cmdsize + 8 + 4) { if (len == p_card->cmdsize + 8 + 4) {
// decode data // decode data
uint16_t mask = (1 << p_card->addrsize) - 1; uint16_t mask = (1 << p_card->addrsize) - 1;
uint16_t addr = (cmd >> 1) & mask; 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 // check received against calculated crc
uint8_t calc_crc = calc_crc4(addr << 1, p_card->cmdsize, byte); 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); Dbprintf("!!! crc mismatch: %x != %x !!!", calc_crc, crc);
return -1; return -1;
} }
@ -453,7 +452,7 @@ void LegicRfSimulate(uint8_t cardtype) {
init_tag(); init_tag();
// verify command line input // verify command line input
if(init_card(cardtype, &card) != 0) { if (init_card(cardtype, &card) != 0) {
DbpString("Unknown tagtype."); DbpString("Unknown tagtype.");
goto OUT; goto OUT;
} }
@ -464,17 +463,17 @@ void LegicRfSimulate(uint8_t cardtype) {
WDT_HIT(); WDT_HIT();
// wait for carrier, restart after timeout // 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; continue;
} }
// wait for connection, restart on error // wait for connection, restart on error
if(setup_phase(&card)) { if (setup_phase(&card)) {
continue; continue;
} }
// conection is established, process commands until one fails // conection is established, process commands until one fails
while(!connected_phase(&card)) { while (!connected_phase(&card)) {
WDT_HIT(); WDT_HIT();
} }
} }

View file

@ -80,7 +80,7 @@ void setT55xxConfig(uint8_t arg0, t55xx_config *c) {
printT55xxConfig(); printT55xxConfig();
#if WITH_FLASH #ifdef WITH_FLASH
// shall persist to flashmem // shall persist to flashmem
if (arg0 == 0) { if (arg0 == 0) {
return; return;
@ -119,7 +119,7 @@ t55xx_config* getT55xxConfig(void) {
} }
void loadT55xxConfig(void) { void loadT55xxConfig(void) {
#if WITH_FLASH #ifdef WITH_FLASH
if (!FlashInit()) { if (!FlashInit()) {
return; 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_PER = GPIO_SSC_DOUT | GPIO_SSC_CLK;
AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT;
AT91C_BASE_PIOA->PIO_ODR = GPIO_SSC_CLK; AT91C_BASE_PIOA->PIO_ODR = GPIO_SSC_CLK;
uint8_t check = 1;
for(;;) { for(;;) {
if ( numcycles > -1 ) { if ( numcycles > -1 ) {
if ( x != numcycles ) { if ( x != numcycles ) {
++x; ++x;
@ -616,9 +618,11 @@ void SimulateTagLowFrequencyEx(int period, int gap, int ledcontrol, int numcycle
// used as a simple detection of a reader field? // used as a simple detection of a reader field?
while (!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) { while (!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) {
WDT_HIT(); WDT_HIT();
if ( usb_poll_validate_length() || BUTTON_PRESS() ) if ( !check ) {
goto OUT; if ( usb_poll_validate_length() || BUTTON_PRESS() )
} goto OUT;
}
++check; }
if (buf[i]) if (buf[i])
OPEN_COIL(); OPEN_COIL();
@ -628,9 +632,11 @@ void SimulateTagLowFrequencyEx(int period, int gap, int ledcontrol, int numcycle
//wait until SSC_CLK goes LOW //wait until SSC_CLK goes LOW
while (AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK) { while (AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK) {
WDT_HIT(); WDT_HIT();
//if ( usb_poll_validate_length() || BUTTON_PRESS() ) if ( !check ) {
if ( BUTTON_PRESS() ) if ( usb_poll_validate_length() || BUTTON_PRESS() )
goto OUT; goto OUT;
}
++check;
} }
i++; 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] // Read one card block in page [page]
void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd) { void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd) {
LED_A_ON(); LED_A_ON();
bool PwdMode = arg0 & 0x1; bool PwdMode = arg0 & 0x1;
uint8_t Page = (arg0 & 0x2) >> 1; uint8_t Page = ( arg0 & 0x2 ) >> 1;
uint32_t i = 0; bool brute_mem = arg0 & 0x4;
bool RegReadMode = (Block == 0xFF);//regular read mode
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 //clear buffer now so it does not interfere with timing later
BigBuf_Clear_keep_EM(); 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 // Set up FPGA, 125kHz to power up the tag
LFSetupFPGAForADC(95, true); LFSetupFPGAForADC(95, true);
// make sure tag is fully powered up... // make sure tag is fully powered up...
WaitMS(4); WaitMS(start_wait);
// Trigger T55x7 Direct Access Mode with start gap // Trigger T55x7 Direct Access Mode with start gap
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
WaitUS(t_config.start_gap); 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 // Turn field on to read the response
// 137*8 seems to get to the start of data pretty well... // 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... // but we want to go past the start and let the repeating data settle in...
TurnReadLFOn(210*8); TurnReadLFOn(200*8);
// Acquisition // Acquisition
// Now do the acquisition // Now do the acquisition
DoPartialAcquisition(0, true, 12000, 0); DoPartialAcquisition(0, true, samples, 0);
// Turn the field off // Turn the field off
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off if ( !brute_mem ) {
cmd_send(CMD_ACK,0,0,0,0,0); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LED_A_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){ 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? //Wait 20ms for write to complete?
WaitMS(7); WaitMS(7);
//Capture response if one exists
DoPartialAcquisition(20, true, 6000, 1000); DoPartialAcquisition(20, true, 6000, 1000);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
@ -1994,7 +2112,7 @@ This triggers a COTAG tag to response
*/ */
void Cotag(uint32_t arg0) { void Cotag(uint32_t arg0) {
#ifndef OFF #ifndef OFF
# define OFF { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); WaitUS(2035); } # define OFF(x) { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); WaitUS((x)); }
#endif #endif
#ifndef ON #ifndef ON
# define ON(x) { FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); WaitUS((x)); } # 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(); LED_A_ON();
// Switching to LF image on FPGA. This might empty BigBuff LFSetupFPGAForADC(89, true);
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
//clear buffer now so it does not interfere with timing later //clear buffer now so it does not interfere with timing later
BigBuf_Clear_ext(false); 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 //send COTAG start pulse
ON(740) OFF ON(740) OFF(2035)
ON(3330) OFF ON(3330) OFF(2035)
ON(740) OFF ON(740) OFF(2035)
ON(1000) ON(1000)
switch(rawsignal) { switch(rawsignal) {

View file

@ -117,21 +117,21 @@ void LFSetupFPGAForADC(int divisor, bool lf_field) {
* @return the number of bits occupied by the samples. * @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) { 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(); uint8_t *dest = BigBuf_get_addr();
bufsize = (bufsize > 0 && bufsize < BigBuf_max_traceLen()) ? bufsize : BigBuf_max_traceLen(); bufsize = (bufsize > 0 && bufsize < BigBuf_max_traceLen()) ? bufsize : BigBuf_max_traceLen();
if (bits_per_sample < 1) bits_per_sample = 1; if (bits_per_sample < 1) bits_per_sample = 1;
if (bits_per_sample > 8) bits_per_sample = 8; if (bits_per_sample > 8) bits_per_sample = 8;
if (decimation < 1) decimation = 1; 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}; BitstreamOut data = { dest , 0, 0};
int sample_counter = 0; int sample_counter = 0;
uint8_t sample = 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_sum =0 ;
uint32_t sample_total_numbers = 0; uint32_t sample_total_numbers = 0;
uint32_t sample_total_saved = 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() ) { while (!BUTTON_PRESS() && !usb_poll_validate_length() ) {
WDT_HIT(); 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) { if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR; sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
// Testpoint 8 (TP8) can be used to trigger oscilliscope
LED_D_OFF(); LED_D_OFF();
// threshold either high or low values 128 = center 0. if trigger = 178 // 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 ((trigger_threshold > 0) && (sample < (trigger_threshold + 128)) && (sample > (128 - trigger_threshold))) {
if (cancel_after > 0) { if (cancel_after > 0) {
@ -162,24 +162,26 @@ uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averag
if (averaging) if (averaging)
sample_sum += sample; sample_sum += sample;
//Check decimation // check decimation
if (decimation > 1) { if (decimation > 1) {
sample_counter++; sample_counter++;
if (sample_counter < decimation) continue; if (sample_counter < decimation) continue;
sample_counter = 0; sample_counter = 0;
} }
//Averaging // averaging
if (averaging && decimation > 1) { if (averaging && decimation > 1) {
sample = sample_sum / decimation; sample = sample_sum / decimation;
sample_sum =0; sample_sum =0;
} }
//Store the sample // store the sample
sample_total_saved ++; sample_total_saved ++;
if (bits_per_sample == 8){ if (bits_per_sample == 8) {
dest[sample_total_saved-1] = sample; 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; if (sample_total_saved >= bufsize) break;
} else { } 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 > 4) pushBit(&data, sample & 0x08);
if (bits_per_sample > 5) pushBit(&data, sample & 0x04); if (bits_per_sample > 5) pushBit(&data, sample & 0x04);
if (bits_per_sample > 6) pushBit(&data, sample & 0x02); 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) ) { while(!BUTTON_PRESS() && !usb_poll_validate_length() && skipCnt < 1000 && (i < bufsize) ) {
WDT_HIT(); 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) { if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
curSample = (uint8_t)AT91C_BASE_SSC->SSC_RHR; curSample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
LED_D_OFF(); 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)) ) { while (!BUTTON_PRESS() && !usb_poll_validate_length() && (i < bufsize) && (noise_counter < (COTAG_T1 << 1)) ) {
WDT_HIT(); 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) { if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR; sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
LED_D_OFF(); LED_D_OFF();
@ -406,12 +401,8 @@ uint32_t doCotagAcquisitionManchester() {
uint16_t noise_counter = 0; uint16_t noise_counter = 0;
while (!BUTTON_PRESS() && !usb_poll_validate_length() && (sample_counter < bufsize) && (noise_counter < (COTAG_T1 << 1)) ) { while (!BUTTON_PRESS() && !usb_poll_validate_length() && (sample_counter < bufsize) && (noise_counter < (COTAG_T1 << 1)) ) {
WDT_HIT(); 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) { if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR; sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
LED_D_OFF(); LED_D_OFF();

View file

@ -1259,7 +1259,6 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da
LED_A_ON(); LED_A_ON();
if ( firstchunk ) { if ( firstchunk ) {
clear_trace(); clear_trace();
set_tracing(false); 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 sectors
} // end loop keys } // end loop keys
} // end loop strategy 2 } // end loop strategy 2
OUT: OUT:
LEDsoff(); LEDsoff();
crypto1_destroy(pcs); crypto1_destroy(pcs);
// All keys found, send to client, or last keychunk from client // All keys found, send to client, or last keychunk from client
if (foundkeys == allkeys || lastchunk ) { if (foundkeys == allkeys || lastchunk ) {
uint64_t foo = 0; uint64_t foo = 0;
for (uint8_t m = 0; m < 64; m++) {
foo |= ((uint64_t)(found[m] & 1) << m);
}
uint16_t bar = 0; uint16_t bar = 0;
for (uint8_t m = 0; m < 64; ++m) uint8_t j = 0;
foo |= (found[m] << m); for (uint8_t m=64; m < sizeof(found); m++) {
for (uint8_t m=64; m < sizeof(found); ++m) bar |= ((uint16_t)(found[m] & 1) << j++);
bar |= (found[m] << (m-64)); }
uint8_t *tmp = BigBuf_malloc(480+10); uint8_t *tmp = BigBuf_malloc(480+10);
memcpy(tmp, k_sector, sectorcnt * sizeof(sector_t) ); memcpy(tmp, k_sector, sectorcnt * sizeof(sector_t) );
num_to_bytes(foo, 8, tmp+480); num_to_bytes(foo, 8, tmp+480);
tmp[488] = bar & 0xFF; tmp[488] = bar & 0xFF;
tmp[489] = bar >> 8 & 0xFF; tmp[489] = bar >> 8 & 0xFF;
cmd_send(CMD_ACK, foundkeys, 0, 0, tmp, 480+10); cmd_send(CMD_ACK, foundkeys, 0, 0, tmp, 480+10);
set_tracing(false); set_tracing(false);

View file

@ -22,7 +22,7 @@
* *
* This is free software: you can redistribute it and/or modify * 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 * 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, * This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of

View file

@ -299,29 +299,29 @@ lualibs/mf_default_keys.lua : default_keys.dic
clean: clean:
$(RM) $(CLEAN) $(RM) $(CLEAN)
cd ../liblua && make clean cd ../liblua && $(MAKE) clean
cd $(JANSSONLIBPATH) && make clean cd $(JANSSONLIBPATH) && $(MAKE) clean
cd $(MBEDTLSLIBPATH) && make clean cd $(MBEDTLSLIBPATH) && $(MAKE) clean
cd $(CBORLIBPATH) && make clean cd $(CBORLIBPATH) && $(MAKE) clean
tarbin: $(BINS) tarbin: $(BINS)
$(TAR) $(TARFLAGS) ../proxmark3-$(platform)-bin.tar $(BINS:%=client/%) $(WINBINS:%=client/%) $(TAR) $(TARFLAGS) ../proxmark3-$(platform)-bin.tar $(BINS:%=client/%) $(WINBINS:%=client/%)
lua_build: lua_build:
@echo Compiling liblua, using platform $(LUAPLATFORM) @echo Compiling liblua, using platform $(LUAPLATFORM)
cd ../liblua && make $(LUAPLATFORM) cd ../liblua && $(MAKE) $(LUAPLATFORM)
jansson_build: jansson_build:
@echo Compiling jansson @echo Compiling jansson
cd $(JANSSONLIBPATH) && make all cd $(JANSSONLIBPATH) && $(MAKE) all
mbedtls_build: mbedtls_build:
@echo Compiling mbedtls @echo Compiling mbedtls
cd $(MBEDTLSLIBPATH) && make all cd $(MBEDTLSLIBPATH) && $(MAKE) all
cbor_build: cbor_build:
@echo Compiling tinycbor @echo Compiling tinycbor
cd $(CBORLIBPATH) && make all cd $(CBORLIBPATH) && $(MAKE) all
.PHONY: all clean .PHONY: all clean

View file

@ -1786,7 +1786,7 @@ int Cmdbin2hex(const char *Cmd) {
//Number of digits supplied as argument //Number of digits supplied as argument
size_t length = en - bg + 1; size_t length = en - bg + 1;
size_t bytelen = (length+7) / 8; 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); memset(arr, 0, bytelen);
BitstreamOut bout = { arr, 0, 0 }; BitstreamOut bout = { arr, 0, 0 };

View file

@ -7,6 +7,8 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Proxmark3 RDV40 Flash memory commands // Proxmark3 RDV40 Flash memory commands
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#ifdef WITH_FLASH
#include "cmdflashmem.h" #include "cmdflashmem.h"
#include "mbedtls/rsa.h" #include "mbedtls/rsa.h"
@ -604,3 +606,5 @@ int CmdHelp(const char *Cmd) {
CmdsHelp(CommandTable); CmdsHelp(CommandTable);
return 0; return 0;
} }
#endif

View file

@ -8,6 +8,8 @@
// Proxmark3 RDV40 Flash memory commands // Proxmark3 RDV40 Flash memory commands
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#ifdef WITH_FLASH
#ifndef CMDFLASHMEM_H__ #ifndef CMDFLASHMEM_H__
#define CMDFLASHMEM_H__ #define CMDFLASHMEM_H__
@ -38,4 +40,6 @@ extern int CmdFlashMemLoad(const char* cmd);
extern int CmdFlashMemSave(const char* cmd); extern int CmdFlashMemSave(const char* cmd);
extern int CmdFlashMemWipe(const char *Cmd); extern int CmdFlashMemWipe(const char *Cmd);
extern int CmdFlashMemInfo(const char *Cmd); extern int CmdFlashMemInfo(const char *Cmd);
#endif
#endif #endif

View file

@ -1,6 +1,6 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Copyright (C) 2010 iZsh <izsh at fail0verflow.com>, Hagen Fritsch // Copyright (C) 2010 iZsh <izsh at fail0verflow.com>, Hagen Fritsch
// 2011, 2017 Merlok // 2011, 2017 - 2019 Merlok
// 2014, Peter Fillmore // 2014, Peter Fillmore
// 2015, 2016, 2017 Iceman // 2015, 2016, 2017 Iceman
// //
@ -12,6 +12,8 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "cmdhf14a.h" #include "cmdhf14a.h"
bool APDUInFramingEnable = true;
static int CmdHelp(const char *Cmd); static int CmdHelp(const char *Cmd);
static int waitCmd(uint8_t iLen); static int waitCmd(uint8_t iLen);
@ -147,6 +149,10 @@ char* getTagInfo(uint8_t uid) {
return manufactureMapping[len-1].desc; 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) { 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 or 10 byte UID\n");
PrintAndLogEx(NORMAL, "\n Emulating ISO/IEC 14443 type A tag with 4,7 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"), (tb1 ? "" : " NOT"),
(tc1 ? "" : " NOT"), (tc1 ? "" : " NOT"),
fsci, fsci,
fsci < 5 ? (fsci - 2) * 8 : fsci < sizeof(atsFSC) ? atsFSC[fsci] : -1
fsci < 8 ? (fsci - 3) * 32 :
fsci == 8 ? 256 :
-1
); );
} }
pos = 2; pos = 2;
@ -836,15 +839,90 @@ int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leav
return 0; return 0;
} }
int CmdExchangeAPDU(uint8_t *datain, int datainlen, bool activateField, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, bool *chaining) { int SelectCard14443_4(bool disconnect, iso14a_card_select_t *card) {
uint16_t cmdc = 0; UsbCommand resp;
*chaining = false; frameLength = 0;
if (card)
memset(card, 0, sizeof(iso14a_card_select_t));
if (activateField) { DropField();
cmdc |= ISO14A_CONNECT;
// 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 // "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 // https://stackoverflow.com/questions/32994936/safe-max-java-card-apdu-data-command-and-respond-size
// here length USB_CMD_DATA_SIZE=512 // 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; uint8_t *recv;
UsbCommand resp; 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)) { if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
recv = resp.d.asBytes; recv = resp.d.asBytes;
int iLen = resp.arg[0]; int iLen = resp.arg[0];
@ -883,13 +949,20 @@ int CmdExchangeAPDU(uint8_t *datain, int datainlen, bool activateField, uint8_t
return 2; return 2;
} }
// I-block ACK
if ((res & 0xf2) == 0xa2) {
*dataoutlen = 0;
*chainingout = true;
return 0;
}
if(!iLen) { if(!iLen) {
PrintAndLogEx(ERR, "APDU: No APDU response."); PrintAndLogEx(ERR, "APDU: No APDU response.");
return 1; return 1;
} }
// check apdu length // check apdu length
if (iLen < 4 && iLen >= 0) { if (iLen < 2 && iLen >= 0) {
PrintAndLogEx(ERR, "APDU: Small APDU response. Len=%d", iLen); PrintAndLogEx(ERR, "APDU: Small APDU response. Len=%d", iLen);
return 2; return 2;
} }
@ -904,7 +977,7 @@ int CmdExchangeAPDU(uint8_t *datain, int datainlen, bool activateField, uint8_t
// chaining // chaining
if ((res & 0x10) != 0) { if ((res & 0x10) != 0) {
*chaining = true; *chainingout = true;
} }
// CRC Check // 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) { int ExchangeAPDU14a(uint8_t *datain, int datainlen, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen) {
*dataoutlen = 0; *dataoutlen = 0;
bool chaining = false; bool chaining = false;
int res;
int res = CmdExchangeAPDU(datain, datainlen, activateField, dataout, maxdataoutlen, dataoutlen, &chaining);
// 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) { while (chaining) {
// I-block with 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 (res) {
if (!leaveSignalON) if (!leaveSignalON)
@ -1205,16 +1323,48 @@ int CmdHF14AAntiFuzz(const char *cmd) {
return 0; 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, "<enable/disable or 0/1>", 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[] = { static command_t CommandTable[] = {
{"help", CmdHelp, 1, "This help"}, {"help", CmdHelp, 1, "This help"},
{"list", CmdHF14AList, 0, "[Deprecated] List ISO 14443-a history"}, {"list", CmdHF14AList, 0, "[Deprecated] List ISO 14443-a history"},
{"info", CmdHF14AInfo, 0, "Tag information"}, {"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, "<n> Collect n>0 ISO14443-a UIDs in one go"}, {"cuids", CmdHF14ACUIDs, 0, "<n> Collect n>0 ISO14443-a UIDs in one go"},
{"sim", CmdHF14ASim, 0, "<UID> -- Simulate ISO 14443-a tag"}, {"sim", CmdHF14ASim, 0, "<UID> -- Simulate ISO 14443-a tag"},
{"sniff", CmdHF14ASniff, 0, "sniff ISO 14443-a traffic"}, {"sniff", CmdHF14ASniff, 0, "sniff ISO 14443-a traffic"},
{"apdu", CmdHF14AAPDU, 0, "Send ISO 14443-4 APDU to tag"}, {"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"}, {"antifuzz", CmdHF14AAntiFuzz, 0, "Fuzzing the anticollision phase. Warning! Readers may react strange"},
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };

View file

@ -519,21 +519,21 @@ int CmdHF15Info(const char *Cmd) {
SendCommand(&c); SendCommand(&c);
if ( !WaitForResponseTimeout(CMD_ACK, &resp, 2000) ) { if ( !WaitForResponseTimeout(CMD_ACK, &resp, 2000) ) {
PrintAndLogEx(NORMAL, "iso15693 card select failed"); PrintAndLogEx(WARNING, "iso15693 card select failed");
return 1; return 1;
} }
uint32_t status = resp.arg[0]; uint32_t status = resp.arg[0];
if ( status < 2 ) { 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; return 1;
} }
recv = resp.d.asBytes; recv = resp.d.asBytes;
if ( recv[0] & ISO15_RES_ERROR ) { 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; return 3;
} }
@ -575,8 +575,8 @@ int CmdHF15Info(const char *Cmd) {
// Record Activity without enabeling carrier // Record Activity without enabeling carrier
//helptext //helptext
int CmdHF15Record(const char *Cmd) { int CmdHF15Record(const char *Cmd) {
char cmdp = param_getchar(Cmd, 0); char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h' || cmdp == 'H') return usage_15_record(); if (cmdp == 'h') return usage_15_record();
UsbCommand c = {CMD_RECORD_RAW_ADC_SAMPLES_ISO_15693, {0,0,0}}; UsbCommand c = {CMD_RECORD_RAW_ADC_SAMPLES_ISO_15693, {0,0,0}};
clearCommandBuffer(); clearCommandBuffer();
@ -598,8 +598,8 @@ int HF15Reader(const char *Cmd, bool verbose) {
} }
int CmdHF15Reader(const char *Cmd) { int CmdHF15Reader(const char *Cmd) {
char cmdp = param_getchar(Cmd, 0); char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h' || cmdp == 'H') return usage_15_reader(); if (cmdp == 'h') return usage_15_reader();
HF15Reader(Cmd, true); HF15Reader(Cmd, true);
return 0; return 0;
@ -608,16 +608,16 @@ int CmdHF15Reader(const char *Cmd) {
// Simulation is still not working very good // Simulation is still not working very good
// helptext // helptext
int CmdHF15Sim(const char *Cmd) { int CmdHF15Sim(const char *Cmd) {
char cmdp = param_getchar(Cmd, 0); char cmdp =tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) < 1 || cmdp == 'h' || cmdp == 'H') return usage_15_sim(); if (strlen(Cmd) < 1 || cmdp == 'h') return usage_15_sim();
uint8_t uid[8] = {0,0,0,0,0,0,0,0}; uint8_t uid[8] = {0,0,0,0,0,0,0,0};
if (param_gethex(Cmd, 0, uid, 16)) { 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; 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}}; UsbCommand c = {CMD_SIMTAG_ISO_15693, {0, 0, 0}};
memcpy(c.d.asBytes, uid, 8); 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) // (There is no standard way of reading the AFI, allthough some tags support this)
// helptext // helptext
int CmdHF15Afi(const char *Cmd) { int CmdHF15Afi(const char *Cmd) {
char cmdp = param_getchar(Cmd, 0); char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h' || cmdp == 'H') return usage_15_findafi(); 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}}; UsbCommand c = {CMD_ISO_15693_FIND_AFI, {strtol(Cmd, NULL, 0), 0, 0}};
clearCommandBuffer(); clearCommandBuffer();
@ -689,7 +689,7 @@ int CmdHF15Dump(const char*Cmd) {
} }
// detect blocksize from card :) // 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; int blocknum = 0;
uint8_t *recv = NULL; uint8_t *recv = NULL;
@ -764,7 +764,7 @@ int CmdHF15Dump(const char*Cmd) {
} }
int CmdHF15Restore(const char*Cmd) { int CmdHF15Restore(const char*Cmd) {
FILE *file; FILE *f;
uint8_t uid[8]={0x00}; uint8_t uid[8]={0x00};
char filename[FILE_PATH_SIZE] = {0x00}; char filename[FILE_PATH_SIZE] = {0x00};
@ -774,10 +774,10 @@ int CmdHF15Restore(const char*Cmd) {
char newCmdPrefix[255] = {0x00}, tmpCmd[255] = {0x00}; char newCmdPrefix[255] = {0x00}, tmpCmd[255] = {0x00};
char param[FILE_PATH_SIZE]=""; char param[FILE_PATH_SIZE]="";
char hex[255]=""; char hex[255]="";
uint8_t retries = 3, tried = 0; uint8_t retries = 3, tried = 0, i = 0;
int retval=0; int retval=0;
size_t bytes_read; size_t bytes_read;
uint8_t i=0;
while(param_getchar(Cmd, cmdp) != 0x00) { while(param_getchar(Cmd, cmdp) != 0x00) {
switch(tolower(param_getchar(Cmd, cmdp))) { switch(tolower(param_getchar(Cmd, cmdp))) {
case '-': case '-':
@ -785,7 +785,8 @@ int CmdHF15Restore(const char*Cmd) {
switch(param[1]) switch(param[1])
{ {
case '2': case '2':
case 'o': strncpy(newCmdPrefix, " ",sizeof(newCmdPrefix)-1); case 'o':
strncpy(newCmdPrefix, " ", sizeof(newCmdPrefix)-1);
strncat(newCmdPrefix, param, sizeof(newCmdPrefix)-1); strncat(newCmdPrefix, param, sizeof(newCmdPrefix)-1);
break; break;
default: default:
@ -815,18 +816,18 @@ int CmdHF15Restore(const char*Cmd) {
default: default:
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
return usage_15_restore(); return usage_15_restore();
break;
} }
cmdp++; cmdp++;
} }
PrintAndLogEx(INFO,"Blocksize: %u",blocksize); PrintAndLogEx(INFO,"Blocksize: %u",blocksize);
if(filename[0]=='\0')
{ if ( !strlen(filename)) {
PrintAndLogEx(WARNING,"Please provide a 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); PrintAndLogEx(WARNING, "Could not find file %s", filename);
return 2; return 2;
} }
@ -835,40 +836,43 @@ int CmdHF15Restore(const char*Cmd) {
PrintAndLogEx(WARNING, "No tag found"); PrintAndLogEx(WARNING, "No tag found");
return 3; return 3;
} }
while (1) { while (1) {
tried=0; tried = 0;
hex[0]=0x00; hex[0] = 0x00;
tmpCmd[0]=0x00; tmpCmd[0] = 0x00;
bytes_read = fread( buff, 1, blocksize, file ); bytes_read = fread( buff, 1, blocksize, f );
if ( bytes_read == 0) { if ( bytes_read == 0) {
PrintAndLogEx(SUCCESS, "File reading done (%s).", filename); PrintAndLogEx(SUCCESS, "File reading done `%s`", filename);
fclose(file); fclose(f);
return 0; 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); PrintAndLogEx(WARNING, "File reading error (%s), %u bytes read instead of %u bytes.", filename, bytes_read, blocksize);
fclose(file); fclose(f);
return 2; return 2;
} }
for(int j=0;j<blocksize;j++)
snprintf(hex+j*2,3,"%02X", (unsigned char)buff[j]); for(int j=0; j < blocksize; j++)
for(int j=0;j<sizeof(uid)/sizeof(uid[0]);j++) snprintf(hex+j*2, 3, "%02X", buff[j]);
for(int j=0; j < sizeof(uid)/sizeof(uid[0]); j++)
snprintf(buff+j*2,3,"%02X", uid[j]); snprintf(buff+j*2,3,"%02X", uid[j]);
//TODO: Addressed mode currently not work //TODO: Addressed mode currently not work
//snprintf(tmpCmd, sizeof(tmpCmd), "%s %s %d %s", newCmdPrefix, buff, i, hex); //snprintf(tmpCmd, sizeof(tmpCmd), "%s %s %d %s", newCmdPrefix, buff, i, hex);
snprintf(tmpCmd, sizeof(tmpCmd), "%s u %d %s", newCmdPrefix, i, hex); snprintf(tmpCmd, sizeof(tmpCmd), "%s u %u %s", newCmdPrefix, i, hex);
PrintAndLogEx(DEBUG, "Command to be sent: %s", tmpCmd); PrintAndLogEx(DEBUG, "Command to be sent| %s", tmpCmd);
for(tried=0;tried<retries;tried++) for(tried=0; tried < retries; tried++)
if(!(retval=CmdHF15Write(tmpCmd))) if(!(retval = CmdHF15Write(tmpCmd)))
break; break;
if(tried >= retries) if(tried >= retries)
return retval; return retval;
i++; i++;
} }
fclose(file); fclose(f);
} }
int CmdHF15List(const char *Cmd) { int CmdHF15List(const char *Cmd) {
@ -1241,7 +1245,7 @@ int CmdHF15Write(const char *Cmd) {
AddCrc(req, reqlen); AddCrc(req, reqlen);
c.arg[0] = reqlen+2; 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(); clearCommandBuffer();
SendCommand(&c); SendCommand(&c);

View file

@ -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]); PrintAndLogEx(FAILED, "Error in step %d, Return code: %d",resp.arg[0],(int)resp.arg[1]);
} else { } else {
size_t nonce_length = resp.arg[1]; 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++) { for(int j = 0; j < nonce_length; j++) {
sprintf(nonce + (2 * j), "%02X", resp.d.asBytes[j]); sprintf(nonce + (2 * j), "%02X", resp.d.asBytes[j]);
} }

View file

@ -404,7 +404,7 @@ int CmdHFiClassSim(const char *Cmd) {
break; break;
size_t datalen = NUM_CSNS * 24; size_t datalen = NUM_CSNS * 24;
void* dump = malloc(datalen); void* dump = calloc(datalen, sizeof(uint8_t));
if ( !dump ) { if ( !dump ) {
PrintAndLogEx(WARNING, "Failed to allocate memory"); PrintAndLogEx(WARNING, "Failed to allocate memory");
return 2; return 2;
@ -456,7 +456,7 @@ int CmdHFiClassSim(const char *Cmd) {
break; break;
size_t datalen = NUM_CSNS * 24; size_t datalen = NUM_CSNS * 24;
void* dump = malloc(datalen); void* dump = calloc(datalen, sizeof(uint8_t));
if ( !dump ) { if ( !dump ) {
PrintAndLogEx(WARNING, "Failed to allocate memory"); PrintAndLogEx(WARNING, "Failed to allocate memory");
return 2; return 2;
@ -2463,7 +2463,7 @@ static void shave(uint8_t *data, uint8_t len){
data[i] &= 0xFE; data[i] &= 0xFE;
} }
static void generate_rev(uint8_t *data, uint8_t len) { 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)); PrintAndLogEx(SUCCESS, "input permuted key | %s \n", sprint_hex(data, len));
permute_rev(data, len, key); permute_rev(data, len, key);
PrintAndLogEx(SUCCESS, " unpermuted key | %s \n", sprint_hex(key, len)); 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); free(key);
} }
static void generate(uint8_t *data, uint8_t len) { static void generate(uint8_t *data, uint8_t len) {
uint8_t *key = calloc(len,1); uint8_t *key = calloc(len, sizeof(uint8_t));
uint8_t *pkey = calloc(len,1); uint8_t *pkey = calloc(len, sizeof(uint8_t));
PrintAndLogEx(SUCCESS, " input key | %s \n", sprint_hex(data, len)); PrintAndLogEx(SUCCESS, " input key | %s \n", sprint_hex(data, len));
permute(data, len, pkey); permute(data, len, pkey);
PrintAndLogEx(SUCCESS, "permuted key | %s \n", sprint_hex(pkey, len)); PrintAndLogEx(SUCCESS, "permuted key | %s \n", sprint_hex(pkey, len));

View file

@ -180,15 +180,14 @@ int CmdLegicInfo(const char *Cmd) {
return 1; return 1;
} }
PrintAndLogEx(NORMAL, "Reading tag memory %d b...", card.cardsize); PrintAndLogEx(SUCCESS, "Reading tag memory %d b...", card.cardsize);
// allocate receiver buffer // allocate receiver buffer
uint8_t *data = malloc(card.cardsize); uint8_t *data = calloc(card.cardsize, sizeof(uint8_t));
if (!data) { if (!data) {
PrintAndLogEx(WARNING, "Cannot allocate memory"); PrintAndLogEx(WARNING, "Cannot allocate memory");
return 2; return 2;
} }
memset(data, 0, card.cardsize);
int status = legic_read_mem(0, card.cardsize, 0x55, data, &datalen); int status = legic_read_mem(0, card.cardsize, 0x55, data, &datalen);
if ( status > 0 ) { if ( status > 0 ) {
@ -480,15 +479,20 @@ int CmdLegicRdmem(const char *Cmd) {
uint16_t datalen = 0; uint16_t datalen = 0;
sscanf(Cmd, "%x %x %x", &offset, &len, &iv); 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 // allocate receiver buffer
uint8_t *data = malloc(len); uint8_t *data = calloc(len, sizeof(uint8_t));
if ( !data ){ if ( !data ){
PrintAndLogEx(WARNING, "Cannot allocate memory"); PrintAndLogEx(WARNING, "Cannot allocate memory");
return 2; return -2;
} }
memset(data, 0, len);
int status = legic_read_mem(offset, len, iv, data, &datalen); int status = legic_read_mem(offset, len, iv, data, &datalen);
if ( status == 0 ) { if ( status == 0 ) {
@ -540,9 +544,9 @@ int CmdLegicRfWrite(const char *Cmd) {
} }
// limit number of bytes to write. This is not a 'restore' command. // limit number of bytes to write. This is not a 'restore' command.
if ( (len>>1) > 100 ){ if ( (len >> 1) > 100 ){
PrintAndLogEx(NORMAL, "Max bound on 100bytes to write a one time."); PrintAndLogEx(WARNING, "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"); PrintAndLogEx(WARNING, "Use the 'hf legic restore' command if you want to write the whole tag at once");
errors = true; errors = true;
} }
@ -551,7 +555,7 @@ int CmdLegicRfWrite(const char *Cmd) {
if (data) if (data)
free(data); free(data);
data = malloc(len >> 1); data = calloc(len >> 1, sizeof(uint8_t));
if ( data == NULL ) { if ( data == NULL ) {
PrintAndLogEx(WARNING, "Can't allocate memory. exiting"); PrintAndLogEx(WARNING, "Can't allocate memory. exiting");
errors = true; errors = true;
@ -598,12 +602,12 @@ int CmdLegicRfWrite(const char *Cmd) {
// OUT-OF-BOUNDS checks // OUT-OF-BOUNDS checks
// UID 4+1 bytes can't be written to. // UID 4+1 bytes can't be written to.
if ( offset < 5 ) { 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; return -2;
} }
if ( len + offset >= card.cardsize ) { 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; return -2;
} }
@ -622,7 +626,7 @@ int CmdLegicRfWrite(const char *Cmd) {
legic_chk_iv(&IV); legic_chk_iv(&IV);
PrintAndLogEx(NORMAL, "Writing to tag"); PrintAndLogEx(SUCCESS, "Writing to tag");
UsbCommand c = {CMD_WRITER_LEGIC_RF, {offset, len, IV}}; UsbCommand c = {CMD_WRITER_LEGIC_RF, {offset, len, IV}};
memcpy(c.d.asBytes, data, len); memcpy(c.d.asBytes, data, len);
@ -630,10 +634,18 @@ int CmdLegicRfWrite(const char *Cmd) {
clearCommandBuffer(); clearCommandBuffer();
SendCommand(&c); SendCommand(&c);
if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
PrintAndLogEx(WARNING, "command execution time out"); uint8_t timeout = 0;
return 1; 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; uint8_t isOK = resp.arg[0] & 0xFF;
if ( !isOK ) { if ( !isOK ) {
PrintAndLogEx(WARNING, "Failed writing tag"); PrintAndLogEx(WARNING, "Failed writing tag");
@ -673,7 +685,7 @@ int CmdLegicCalcCrc(const char *Cmd){
// it's possible for user to accidentally enter "b" parameter // it's possible for user to accidentally enter "b" parameter
// more than once - we have to clean previous malloc // more than once - we have to clean previous malloc
if (data) free(data); if (data) free(data);
data = malloc(len >> 1); data = calloc(len >> 1, sizeof(uint8_t) );
if ( data == NULL ) { if ( data == NULL ) {
PrintAndLogEx(WARNING, "Can't allocate memory. exiting"); PrintAndLogEx(WARNING, "Can't allocate memory. exiting");
errors = true; errors = true;
@ -714,10 +726,10 @@ int CmdLegicCalcCrc(const char *Cmd){
switch (type){ switch (type){
case 16: case 16:
init_table(CRC_LEGIC); 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; break;
default: default:
PrintAndLogEx(NORMAL, "Legic crc8: %X", CRC8Legic(data, len) ); PrintAndLogEx(SUCCESS, "Legic crc8: %X", CRC8Legic(data, len) );
break; break;
} }
@ -733,11 +745,18 @@ int legic_read_mem(uint32_t offset, uint32_t len, uint32_t iv, uint8_t *out, uin
clearCommandBuffer(); clearCommandBuffer();
SendCommand(&c); SendCommand(&c);
UsbCommand resp; UsbCommand resp;
if ( !WaitForResponseTimeout(CMD_ACK, &resp, 3000) ) {
PrintAndLogEx(WARNING, "command execution time out"); uint8_t timeout = 0;
return 1; 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; uint8_t isOK = resp.arg[0] & 0xFF;
*outlen = resp.arg[1]; *outlen = resp.arg[1];
if ( !isOK ) { if ( !isOK ) {
@ -762,13 +781,13 @@ int legic_print_type(uint32_t tagtype, uint8_t spaces){
char *spacer = spc + (10-spaces); char *spacer = spc + (10-spaces);
if ( tagtype == 22 ) 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 ) 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 ) 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 else
PrintAndLogEx(NORMAL, "%sTYPE : Unknown %06x", spacer, tagtype); PrintAndLogEx(INFO, "%sTYPE : Unknown %06x", spacer, tagtype);
return 0; return 0;
} }
int legic_get_type(legic_card_select_t *card){ 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){ void legic_chk_iv(uint32_t *iv){
if ( (*iv & 0x7F) != *iv ){ if ( (*iv & 0x7F) != *iv ){
*iv &= 0x7F; *iv &= 0x7F;
PrintAndLogEx(NORMAL, "Truncating IV to 7bits, %u", *iv); PrintAndLogEx(INFO, "Truncating IV to 7bits, %u", *iv);
} }
// IV must be odd // IV must be odd
if ( (*iv & 1) == 0 ){ if ( (*iv & 1) == 0 ){
*iv |= 0x01; *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) { 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"); if ( verbose ) PrintAndLogEx(WARNING, "command execution time out");
return 1; return 1;
case 3: case 3:
if ( verbose ) PrintAndLogEx(NORMAL, "legic card select failed"); if ( verbose ) PrintAndLogEx(WARNING, "legic card select failed");
return 2; return 2;
default: break; 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); legic_print_type(card.cardsize, 0);
return 0; return 0;
} }
@ -882,16 +901,23 @@ int CmdLegicDump(const char *Cmd){
dumplen = card.cardsize; dumplen = card.cardsize;
legic_print_type(dumplen, 0); 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}}; UsbCommand c = {CMD_READER_LEGIC_RF, {0x00, dumplen, 0x55}};
clearCommandBuffer(); clearCommandBuffer();
SendCommand(&c); SendCommand(&c);
UsbCommand resp; UsbCommand resp;
if (!WaitForResponseTimeout(CMD_ACK, &resp, 3000)) {
PrintAndLogEx(NORMAL, "Command execute time-out"); uint8_t timeout = 0;
return 1; 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; uint8_t isOK = resp.arg[0] & 0xFF;
if ( !isOK ) { if ( !isOK ) {
@ -900,12 +926,11 @@ int CmdLegicDump(const char *Cmd){
} }
uint16_t readlen = resp.arg[1]; uint16_t readlen = resp.arg[1];
uint8_t *data = malloc(readlen); uint8_t *data = calloc(readlen, sizeof(uint8_t));
if (!data) { if (!data) {
PrintAndLogEx(WARNING, "Fail, cannot allocate memory"); PrintAndLogEx(WARNING, "Fail, cannot allocate memory");
return 3; return 3;
} }
memset(data, 0, readlen);
if ( readlen != dumplen ) if ( readlen != dumplen )
PrintAndLogEx(WARNING, "Fail, only managed to read 0x%02X bytes of 0x%02X", 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 else
sprintf(fnameptr + fileNlen,".bin"); sprintf(fnameptr + fileNlen,".bin");
f = fopen(filename,"wb"); f = fopen(filename, "wb");
if (!f) { if (!f) {
PrintAndLogEx(WARNING, "Could not create file name %s", filename); PrintAndLogEx(WARNING, "Could not create file name %s", filename);
if (data) if (data)
@ -934,7 +959,7 @@ int CmdLegicDump(const char *Cmd){
fflush(f); fflush(f);
fclose(f); fclose(f);
free(data); free(data);
PrintAndLogEx(NORMAL, "Wrote %d bytes to %s", readlen, filename); PrintAndLogEx(SUCCESS, "Wrote %d bytes to %s", readlen, filename);
return 0; return 0;
} }
@ -982,12 +1007,11 @@ int CmdLegicRestore(const char *Cmd){
numofbytes = card.cardsize; numofbytes = card.cardsize;
// set up buffer // set up buffer
uint8_t *data = malloc(numofbytes); uint8_t *data = calloc(numofbytes, sizeof(uint8_t) );
if (!data) { if (!data) {
PrintAndLogEx(WARNING, "Fail, cannot allocate memory"); PrintAndLogEx(WARNING, "Fail, cannot allocate memory");
return 2; return 2;
} }
memset(data, 0, numofbytes);
legic_print_type(numofbytes, 0); legic_print_type(numofbytes, 0);
@ -997,7 +1021,7 @@ int CmdLegicRestore(const char *Cmd){
f = fopen(filename,"rb"); f = fopen(filename,"rb");
if (!f) { if (!f) {
PrintAndLogEx(NORMAL, "File %s not found or locked", filename); PrintAndLogEx(WARNING, "File %s not found or locked", filename);
return 3; return 3;
} }
@ -1018,12 +1042,12 @@ int CmdLegicRestore(const char *Cmd){
fclose(f); fclose(f);
if ( bytes_read == 0){ if ( bytes_read == 0){
PrintAndLogEx(NORMAL, "File reading error"); PrintAndLogEx(WARNING, "File reading error");
free(data); free(data);
return 2; return 2;
} }
PrintAndLogEx(NORMAL, "Restoring to card"); PrintAndLogEx(SUCCESS, "Restoring to card");
// transfer to device // transfer to device
size_t len = 0; size_t len = 0;
@ -1038,22 +1062,29 @@ int CmdLegicRestore(const char *Cmd){
clearCommandBuffer(); clearCommandBuffer();
SendCommand(&c); SendCommand(&c);
if (!WaitForResponseTimeout(CMD_ACK, &resp, 4000)) { uint8_t timeout = 0;
PrintAndLogEx(WARNING, "command execution time out"); while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
free(data); ++timeout;
return 1; 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; uint8_t isOK = resp.arg[0] & 0xFF;
if ( !isOK ) { if ( !isOK ) {
PrintAndLogEx(WARNING, "Failed writing tag [msg = %u]", resp.arg[1] & 0xFF); PrintAndLogEx(WARNING, "Failed writing tag [msg = %u]", resp.arg[1] & 0xFF);
free(data); free(data);
return 1; 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); 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; return 0;
} }
@ -1077,12 +1108,11 @@ int CmdLegicELoad(const char *Cmd) {
} }
// set up buffer // set up buffer
uint8_t *data = malloc(numofbytes); uint8_t *data = calloc(numofbytes, sizeof(uint8_t));
if (!data) { if (!data) {
PrintAndLogEx(WARNING, "Fail, cannot allocate memory"); PrintAndLogEx(WARNING, "Fail, cannot allocate memory");
return 3; return 3;
} }
memset(data, 0, numofbytes);
// set up file // set up file
len = param_getstr(Cmd, nameParamNo, filename, FILE_PATH_SIZE); len = param_getstr(Cmd, nameParamNo, filename, FILE_PATH_SIZE);
@ -1094,7 +1124,7 @@ int CmdLegicELoad(const char *Cmd) {
// open file // open file
f = fopen(filename,"rb"); f = fopen(filename,"rb");
if (!f) { if (!f) {
PrintAndLogEx(NORMAL, "File %s not found or locked", filename); PrintAndLogEx(WARNING, "File %s not found or locked", filename);
free(data); free(data);
return 1; return 1;
} }
@ -1102,7 +1132,7 @@ int CmdLegicELoad(const char *Cmd) {
// load file // load file
size_t bytes_read = fread(data, 1, numofbytes, f); size_t bytes_read = fread(data, 1, numofbytes, f);
if ( bytes_read == 0){ if ( bytes_read == 0){
PrintAndLogEx(NORMAL, "File reading error"); PrintAndLogEx(WARNING, "File reading error");
free(data); free(data);
fclose(f); fclose(f);
f = NULL; f = NULL;
@ -1115,7 +1145,7 @@ int CmdLegicELoad(const char *Cmd) {
legic_seteml(data, 0, numofbytes); legic_seteml(data, 0, numofbytes);
free(data); 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; return 0;
} }
@ -1146,15 +1176,14 @@ int CmdLegicESave(const char *Cmd) {
fileNlen = FILE_PATH_SIZE - 5; fileNlen = FILE_PATH_SIZE - 5;
// set up buffer // set up buffer
uint8_t *data = malloc(numofbytes); uint8_t *data = calloc(numofbytes, sizeof(uint8_t));
if (!data) { if (!data) {
PrintAndLogEx(WARNING, "Fail, cannot allocate memory"); PrintAndLogEx(WARNING, "Fail, cannot allocate memory");
return 3; return 3;
} }
memset(data, 0, numofbytes);
// download emulator memory // download emulator memory
PrintAndLogEx(NORMAL, "Reading emulator memory..."); PrintAndLogEx(SUCCESS, "Reading emulator memory...");
if (!GetFromDevice( BIG_BUF_EML, data, numofbytes, 0, NULL, 2500, false)) { if (!GetFromDevice( BIG_BUF_EML, data, numofbytes, 0, NULL, 2500, false)) {
PrintAndLogEx(WARNING, "Fail, transfer from device time-out"); PrintAndLogEx(WARNING, "Fail, transfer from device time-out");
free(data); free(data);
@ -1185,16 +1214,15 @@ int CmdLegicWipe(const char *Cmd){
} }
// set up buffer // set up buffer
uint8_t *data = malloc(card.cardsize); uint8_t *data = calloc(card.cardsize, sizeof(uint8_t));
if (!data) { if (!data) {
PrintAndLogEx(WARNING, "Fail, cannot allocate memory"); PrintAndLogEx(WARNING, "Fail, cannot allocate memory");
return 2; return 2;
} }
memset(data, 0, card.cardsize);
legic_print_type(card.cardsize, 0); legic_print_type(card.cardsize, 0);
PrintAndLogEx(NORMAL, "Erasing"); PrintAndLogEx(SUCCESS, "Erasing");
// transfer to device // transfer to device
size_t len = 0; size_t len = 0;
@ -1210,11 +1238,18 @@ int CmdLegicWipe(const char *Cmd){
clearCommandBuffer(); clearCommandBuffer();
SendCommand(&c); SendCommand(&c);
if (!WaitForResponseTimeout(CMD_ACK, &resp, 4000)) { uint8_t timeout = 0;
PrintAndLogEx(WARNING, "command execution time out"); while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
free(data); ++timeout;
return 3; 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; uint8_t isOK = resp.arg[0] & 0xFF;
if ( !isOK ) { if ( !isOK ) {
PrintAndLogEx(WARNING, "Failed writing tag [msg = %u]", resp.arg[1] & 0xFF); PrintAndLogEx(WARNING, "Failed writing tag [msg = %u]", resp.arg[1] & 0xFF);
@ -1222,7 +1257,7 @@ int CmdLegicWipe(const char *Cmd){
return 4; return 4;
} }
} }
PrintAndLogEx(NORMAL, "ok\n"); PrintAndLogEx(SUCCESS, "ok\n");
return 0; return 0;
} }
@ -1236,7 +1271,7 @@ static command_t CommandTable[] = {
{"reader", CmdLegicReader, 1, "LEGIC Prime Reader UID and tag info"}, {"reader", CmdLegicReader, 1, "LEGIC Prime Reader UID and tag info"},
{"info", CmdLegicInfo, 0, "Display deobfuscated and decoded LEGIC Prime tag data"}, {"info", CmdLegicInfo, 0, "Display deobfuscated and decoded LEGIC Prime tag data"},
{"dump", CmdLegicDump, 0, "Dump LEGIC Prime tag to binary file"}, {"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"}, {"rdmem", CmdLegicRdmem, 0, "Read bytes from a LEGIC Prime tag"},
{"sim", CmdLegicRfSim, 0, "Start tag simulator"}, {"sim", CmdLegicRfSim, 0, "Start tag simulator"},
{"write", CmdLegicRfWrite, 0, "Write data to a LEGIC Prime tag"}, {"write", CmdLegicRfWrite, 0, "Write data to a LEGIC Prime tag"},

View file

@ -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_EXTERNAL_AUTHENTICATION :snprintf(exp, size, "EXTERNAL AUTH");break;
case ISO7816_GET_CHALLENGE :snprintf(exp, size, "GET CHALLENGE");break; case ISO7816_GET_CHALLENGE :snprintf(exp, size, "GET CHALLENGE");break;
case ISO7816_MANAGE_CHANNEL :snprintf(exp, size, "MANAGE CHANNEL");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; default :snprintf(exp,size,"?"); break;
} }
} }

View file

@ -11,11 +11,16 @@
#include "cmdhfmf.h" #include "cmdhfmf.h"
#include "mifare4.h" #include "mifare4.h"
#define MIFARE_4K_MAXBLOCK 255 #define MIFARE_4K_MAXBLOCK 256
#define MIFARE_2K_MAXBLOCK 128 #define MIFARE_2K_MAXBLOCK 128
#define MIFARE_1K_MAXBLOCK 64 #define MIFARE_1K_MAXBLOCK 64
#define MIFARE_MINI_MAXBLOCK 20 #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); static int CmdHelp(const char *Cmd);
int usage_hf14_ice(void){ int usage_hf14_ice(void){
@ -415,7 +420,7 @@ int GetHFMF14AUID(uint8_t *uid, int *uidlen) {
char * GenerateFilename(const char *prefix, const char *suffix){ char * GenerateFilename(const char *prefix, const char *suffix){
uint8_t uid[10] = {0,0,0,0,0,0,0,0,0,0}; uint8_t uid[10] = {0,0,0,0,0,0,0,0,0,0};
int uidlen=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); GetHFMF14AUID(uid, &uidlen);
if (!uidlen) { if (!uidlen) {
@ -591,7 +596,7 @@ int CmdHF14AMfRdSc(const char *Cmd) {
} }
sectorNo = param_get8(Cmd, 0); sectorNo = param_get8(Cmd, 0);
if (sectorNo > 39) { if (sectorNo > MIFARE_4K_MAXSECTOR ) {
PrintAndLogEx(NORMAL, "Sector number must be less than 40"); PrintAndLogEx(NORMAL, "Sector number must be less than 40");
return 1; return 1;
} }
@ -645,7 +650,7 @@ int CmdHF14AMfRdSc(const char *Cmd) {
return 0; return 0;
} }
uint8_t NumOfBlocks(char card){ uint16_t NumOfBlocks(char card){
switch(card){ switch(card){
case '0' : return MIFARE_MINI_MAXBLOCK; case '0' : return MIFARE_MINI_MAXBLOCK;
case '1' : return MIFARE_1K_MAXBLOCK; case '1' : return MIFARE_1K_MAXBLOCK;
@ -656,11 +661,11 @@ uint8_t NumOfBlocks(char card){
} }
uint8_t NumOfSectors(char card){ uint8_t NumOfSectors(char card){
switch(card){ switch(card){
case '0' : return 5; case '0' : return MIFARE_MINI_MAXSECTOR;
case '1' : return 16; case '1' : return MIFARE_1K_MAXSECTOR;
case '2' : return 32; case '2' : return MIFARE_2K_MAXSECTOR;
case '4' : return 40; case '4' : return MIFARE_4K_MAXSECTOR;
default : return 16; default : return MIFARE_1K_MAXSECTOR;
} }
} }
@ -729,7 +734,7 @@ int CmdHF14AMfDump(const char *Cmd) {
} }
if ((fin = fopen(keyFilename, "rb")) == NULL) { 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; return 1;
} }
@ -738,7 +743,7 @@ int CmdHF14AMfDump(const char *Cmd) {
for (sectorNo=0; sectorNo<numSectors; sectorNo++) { for (sectorNo=0; sectorNo<numSectors; sectorNo++) {
bytes_read = fread( keyA[sectorNo], 1, 6, fin ); bytes_read = fread( keyA[sectorNo], 1, 6, fin );
if ( bytes_read != 6) { if ( bytes_read != 6) {
PrintAndLogEx(NORMAL, "File reading error."); PrintAndLogEx(WARNING, "File reading error.");
fclose(fin); fclose(fin);
return 2; return 2;
} }
@ -748,7 +753,7 @@ int CmdHF14AMfDump(const char *Cmd) {
for (sectorNo=0; sectorNo<numSectors; sectorNo++) { for (sectorNo=0; sectorNo<numSectors; sectorNo++) {
bytes_read = fread( keyB[sectorNo], 1, 6, fin ); bytes_read = fread( keyB[sectorNo], 1, 6, fin );
if ( bytes_read != 6) { if ( bytes_read != 6) {
PrintAndLogEx(NORMAL, "File reading error."); PrintAndLogEx(WARNING, "File reading error.");
fclose(fin); fclose(fin);
return 2; return 2;
} }
@ -874,13 +879,13 @@ int CmdHF14AMfDump(const char *Cmd) {
} }
if ((fout = fopen(dataFilename,"wb")) == NULL) { if ((fout = fopen(dataFilename,"wb")) == NULL) {
PrintAndLogEx(WARNING, "could not create file name %s", dataFilename); PrintAndLogEx(WARNING, "could not create file name " _YELLOW_(%s), dataFilename);
return 1; return 1;
} }
uint16_t numblocks = FirstBlockOfSector(numSectors - 1) + NumBlocksPerSector(numSectors - 1); uint16_t numblocks = FirstBlockOfSector(numSectors - 1) + NumBlocksPerSector(numSectors - 1);
fwrite(carddata, 1, 16*numblocks, fout); fwrite(carddata, 1, 16*numblocks, fout);
fclose(fout); fclose(fout);
PrintAndLogEx(SUCCESS, "dumped %d blocks (%d bytes) to file %s", numblocks, 16*numblocks, dataFilename); PrintAndLogEx(SUCCESS, "dumped %d blocks (%d bytes) to file " _YELLOW_(%s), numblocks, 16*numblocks, dataFilename);
} }
return 0; return 0;
} }
@ -940,7 +945,7 @@ int CmdHF14AMfRestore(const char *Cmd) {
} }
if ((fkeys = fopen(keyFilename, "rb")) == NULL) { if ((fkeys = fopen(keyFilename, "rb")) == NULL) {
PrintAndLogEx(WARNING, "Could not find file %s", keyFilename); PrintAndLogEx(WARNING, "Could not find file " _YELLOW_(%s), keyFilename);
return 1; return 1;
} }
@ -948,7 +953,7 @@ int CmdHF14AMfRestore(const char *Cmd) {
for (sectorNo = 0; sectorNo < numSectors; sectorNo++) { for (sectorNo = 0; sectorNo < numSectors; sectorNo++) {
bytes_read = fread( keyA[sectorNo], 1, 6, fkeys ); bytes_read = fread( keyA[sectorNo], 1, 6, fkeys );
if ( bytes_read != 6 ) { if ( bytes_read != 6 ) {
PrintAndLogEx(NORMAL, "File reading error (%s).", keyFilename); PrintAndLogEx(WARNING, "File reading error " _YELLOW_(%s), keyFilename);
fclose(fkeys); fclose(fkeys);
return 2; return 2;
} }
@ -957,7 +962,7 @@ int CmdHF14AMfRestore(const char *Cmd) {
for (sectorNo = 0; sectorNo < numSectors; sectorNo++) { for (sectorNo = 0; sectorNo < numSectors; sectorNo++) {
bytes_read = fread( keyB[sectorNo], 1, 6, fkeys ); bytes_read = fread( keyB[sectorNo], 1, 6, fkeys );
if ( bytes_read != 6 ) { if ( bytes_read != 6 ) {
PrintAndLogEx(NORMAL, "File reading error (%s).", keyFilename); PrintAndLogEx(WARNING, "File reading error " _YELLOW_(%s), keyFilename);
fclose(fkeys); fclose(fkeys);
return 2; return 2;
} }
@ -974,10 +979,10 @@ int CmdHF14AMfRestore(const char *Cmd) {
} }
if ((fdump = fopen(dataFilename, "rb")) == NULL) { if ((fdump = fopen(dataFilename, "rb")) == NULL) {
PrintAndLogEx(WARNING, "Could not find file %s", dataFilename); PrintAndLogEx(WARNING, "Could not find file " _YELLOW_(%s), dataFilename);
return 1; return 1;
} }
PrintAndLogEx(NORMAL, "Restoring %s to card", dataFilename); PrintAndLogEx(INFO, "Restoring " _YELLOW_(%s)" to card", dataFilename);
for (sectorNo = 0; sectorNo < numSectors; sectorNo++) { for (sectorNo = 0; sectorNo < numSectors; sectorNo++) {
for (blockNo = 0; blockNo < NumBlocksPerSector(sectorNo); blockNo++) { for (blockNo = 0; blockNo < NumBlocksPerSector(sectorNo); blockNo++) {
@ -985,7 +990,7 @@ int CmdHF14AMfRestore(const char *Cmd) {
memcpy(c.d.asBytes, key, 6); memcpy(c.d.asBytes, key, 6);
bytes_read = fread(bldata, 1, 16, fdump); bytes_read = fread(bldata, 1, 16, fdump);
if ( bytes_read != 16) { if ( bytes_read != 16) {
PrintAndLogEx(NORMAL, "File reading error (%s).", dataFilename); PrintAndLogEx(WARNING, "File reading error " _YELLOW_(%s), dataFilename);
fclose(fdump); fclose(fdump);
fdump = NULL; fdump = NULL;
return 2; return 2;
@ -1015,9 +1020,9 @@ int CmdHF14AMfRestore(const char *Cmd) {
UsbCommand resp; UsbCommand resp;
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
uint8_t isOK = resp.arg[0] & 0xff; uint8_t isOK = resp.arg[0] & 0xff;
PrintAndLogEx(NORMAL, "isOk:%02x", isOK); PrintAndLogEx(SUCCESS, "isOk:%02x", isOK);
} else { } else {
PrintAndLogEx(NORMAL, "Command execute timeout"); PrintAndLogEx(WARNING, "Command execute timeout");
} }
} }
} }
@ -1187,7 +1192,7 @@ int CmdHF14AMfNested(const char *Cmd) {
// 20160116 If Sector A is found, but not Sector B, try just reading it of the tag? // 20160116 If Sector A is found, but not Sector B, try just reading it of the tag?
PrintAndLogEx(SUCCESS, "trying to read key B..."); PrintAndLogEx(INFO, "trying to read key B...");
for (i = 0; i < SectorsCnt; i++) { for (i = 0; i < SectorsCnt; i++) {
// KEY A but not KEY B // KEY A but not KEY B
if ( e_sector[i].foundKey[0] && !e_sector[i].foundKey[1] ) { if ( e_sector[i].foundKey[0] && !e_sector[i].foundKey[1] ) {
@ -1230,8 +1235,8 @@ int CmdHF14AMfNested(const char *Cmd) {
if (e_sector[i].foundKey[1]) if (e_sector[i].foundKey[1])
num_to_bytes(e_sector[i].Key[1], 6, &keyBlock[10]); num_to_bytes(e_sector[i].Key[1], 6, &keyBlock[10]);
mfEmlSetMem(keyBlock, FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1, 1); mfEmlSetMem(keyBlock, FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1, 1);
PrintAndLogEx(SUCCESS, "key transferred to emulator memory."); }
} PrintAndLogEx(SUCCESS, "key transferred to emulator memory.");
} }
// Create dump file // Create dump file
@ -1241,12 +1246,12 @@ int CmdHF14AMfNested(const char *Cmd) {
return 1; return 1;
if ((fkeys = fopen(fptr, "wb")) == NULL) { if ((fkeys = fopen(fptr, "wb")) == NULL) {
PrintAndLogEx(WARNING, "could not create file %s", fptr); PrintAndLogEx(WARNING, "could not create file " _YELLOW_(%s), fptr);
free(e_sector); free(e_sector);
return 1; return 1;
} }
PrintAndLogEx(SUCCESS, "saving keys to binary file %s...", fptr); PrintAndLogEx(SUCCESS, "saving keys to binary file " _YELLOW_(%s), fptr);
for (i=0; i<SectorsCnt; i++) { for (i=0; i<SectorsCnt; i++) {
if (e_sector[i].foundKey[0]){ if (e_sector[i].foundKey[0]){
num_to_bytes(e_sector[i].Key[0], 6, tempkey); num_to_bytes(e_sector[i].Key[0], 6, tempkey);
@ -1314,14 +1319,14 @@ int CmdHF14AMfNestedHard(const char *Cmd) {
default: default:
if (param_getchar(Cmd, cmdp) == 0x00) if (param_getchar(Cmd, cmdp) == 0x00)
{ {
PrintAndLogEx(NORMAL, "Block number is missing"); PrintAndLogEx(WARNING, "Block number is missing");
return 1; return 1;
} }
blockNo = param_get8(Cmd, cmdp); blockNo = param_get8(Cmd, cmdp);
ctmp = tolower(param_getchar(Cmd, cmdp+1)); ctmp = tolower(param_getchar(Cmd, cmdp+1));
if (ctmp != 'a' && ctmp != 'b') { if (ctmp != 'a' && ctmp != 'b') {
PrintAndLogEx(NORMAL, "Key type must be A or B"); PrintAndLogEx(WARNING, "Key type must be A or B");
return 1; return 1;
} }
@ -1330,13 +1335,13 @@ int CmdHF14AMfNestedHard(const char *Cmd) {
} }
if (param_gethex(Cmd, cmdp+2, key, 12)) { if (param_gethex(Cmd, cmdp+2, key, 12)) {
PrintAndLogEx(NORMAL, "Key must include 12 HEX symbols"); PrintAndLogEx(WARNING, "Key must include 12 HEX symbols");
return 1; return 1;
} }
if (param_getchar(Cmd, cmdp+3) == 0x00) if (param_getchar(Cmd, cmdp+3) == 0x00)
{ {
PrintAndLogEx(NORMAL, "Target block number is missing"); PrintAndLogEx(WARNING, "Target block number is missing");
return 1; return 1;
} }
@ -1344,7 +1349,7 @@ int CmdHF14AMfNestedHard(const char *Cmd) {
ctmp = tolower(param_getchar(Cmd, cmdp+4)); ctmp = tolower(param_getchar(Cmd, cmdp+4));
if (ctmp != 'a' && ctmp != 'b') { if (ctmp != 'a' && ctmp != 'b') {
PrintAndLogEx(NORMAL, "Target key type must be A or B"); PrintAndLogEx(WARNING, "Target key type must be A or B");
return 1; return 1;
} }
if (ctmp != 'a') { if (ctmp != 'a') {
@ -1402,7 +1407,7 @@ int CmdHF14AMfNestedHard(const char *Cmd) {
SetSIMDInstr(SIMD_NONE); SetSIMDInstr(SIMD_NONE);
break; break;
default: default:
PrintAndLog("Unknown SIMD type. %c", ctmp); PrintAndLogEx(WARNING, "Unknown SIMD type. %c", ctmp);
return 1; return 1;
} }
cmdp += 2; cmdp += 2;
@ -1420,7 +1425,7 @@ int CmdHF14AMfNestedHard(const char *Cmd) {
// check if we can authenticate to sector // check if we can authenticate to sector
int res = mfCheckKeys(blockNo, keyType, true, 1, key, &key64); int res = mfCheckKeys(blockNo, keyType, true, 1, key, &key64);
if (res) { if (res) {
PrintAndLogEx(NORMAL, "Key is wrong. Can't authenticate to block:%3d key type:%c", blockNo, keyType ? 'B' : 'A'); PrintAndLogEx(WARNING, "Key is wrong. Can't authenticate to block:%3d key type:%c", blockNo, keyType ? 'B' : 'A');
return 3; return 3;
} }
} }
@ -1497,11 +1502,11 @@ int CmdHF14AMfChk_fast(const char *Cmd) {
// sectors // sectors
switch(ctmp) { switch(ctmp) {
case '0': sectorsCnt = 5; break; case '0': sectorsCnt = MIFARE_MINI_MAXSECTOR; break;
case '1': sectorsCnt = 16; break; case '1': sectorsCnt = MIFARE_1K_MAXSECTOR; break;
case '2': sectorsCnt = 32; break; case '2': sectorsCnt = MIFARE_2K_MAXSECTOR; break;
case '4': sectorsCnt = 40; break; case '4': sectorsCnt = MIFARE_4K_MAXSECTOR; break;
default: sectorsCnt = 16; default: sectorsCnt = MIFARE_1K_MAXSECTOR;
} }
for (i = 1; param_getchar(Cmd, i); i++) { for (i = 1; param_getchar(Cmd, i); i++) {
@ -1542,7 +1547,7 @@ int CmdHF14AMfChk_fast(const char *Cmd) {
f = fopen( filename, "r"); f = fopen( filename, "r");
if ( !f ){ if ( !f ){
PrintAndLogEx(FAILED, "File: %s: not found or locked.", filename); PrintAndLogEx(FAILED, "File: " _YELLOW_(%s) ": not found or locked.", filename);
continue; continue;
} }
@ -1556,7 +1561,7 @@ int CmdHF14AMfChk_fast(const char *Cmd) {
if( buf[0]=='#' ) continue; //The line start with # is comment, skip if( buf[0]=='#' ) continue; //The line start with # is comment, skip
if (!isxdigit(buf[0])){ 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; continue;
} }
@ -1578,7 +1583,7 @@ int CmdHF14AMfChk_fast(const char *Cmd) {
memset(buf, 0, sizeof(buf)); memset(buf, 0, sizeof(buf));
} }
fclose(f); fclose(f);
PrintAndLogEx(SUCCESS, "Loaded %2d keys from %s", keycnt, filename); PrintAndLogEx(SUCCESS, "Loaded %2d keys from " _YELLOW_(%s), keycnt, filename);
} }
} }
@ -1617,7 +1622,7 @@ int CmdHF14AMfChk_fast(const char *Cmd) {
if (ukbhit()) { if (ukbhit()) {
int gc = getchar(); (void)gc; int gc = getchar(); (void)gc;
PrintAndLogEx(NORMAL, "\naborted via keyboard!\n"); PrintAndLogEx(WARNING, "\naborted via keyboard!\n");
goto out; goto out;
} }
@ -1644,47 +1649,63 @@ out:
t1 = msclock() - t1; t1 = msclock() - t1;
PrintAndLogEx(SUCCESS, "Time in checkkeys (fast): %.1fs\n", (float)(t1/1000.0)); PrintAndLogEx(SUCCESS, "Time in checkkeys (fast): %.1fs\n", (float)(t1/1000.0));
printKeyTable( sectorsCnt, e_sector ); // check..
uint8_t found_keys = 0;
if (transferToEml) { for (uint8_t i = 0; i < sectorsCnt; ++i) {
uint8_t block[16] = {0x00};
for (uint8_t i = 0; i < sectorsCnt; ++i ) { if ( e_sector[i].foundKey[0] )
mfEmlGetMem(block, FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1, 1); found_keys++;
if (e_sector[i].foundKey[0])
num_to_bytes(e_sector[i].Key[0], 6, block); if ( e_sector[i].foundKey[1] )
if (e_sector[i].foundKey[1]) found_keys++;
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");
} }
if (createDumpFile) { if ( found_keys == 0 ) {
fptr = GenerateFilename("hf-mf-", "-key.bin"); PrintAndLogEx(WARNING, "No keys found");
if (fptr == NULL) } else {
return 1;
FILE *fkeys = fopen(fptr, "wb");
if (fkeys == NULL) {
PrintAndLogEx(WARNING, "Could not create file %s", fptr);
free(keyBlock);
free(e_sector);
return 1;
}
PrintAndLogEx(NORMAL, "Printing keys to binary file %s...", fptr);
for (i=0; i<sectorsCnt; i++) { printKeyTable( sectorsCnt, e_sector );
num_to_bytes(e_sector[i].Key[0], 6, tempkey);
fwrite (tempkey, 1, 6, fkeys);
}
for (i=0; i<sectorsCnt; i++) { if (transferToEml) {
num_to_bytes(e_sector[i].Key[1], 6, tempkey); uint8_t block[16] = {0x00};
fwrite (tempkey, 1, 6, fkeys ); for (uint8_t i = 0; i < sectorsCnt; ++i ) {
mfEmlGetMem(block, FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1, 1);
if (e_sector[i].foundKey[0])
num_to_bytes(e_sector[i].Key[0], 6, block);
if (e_sector[i].foundKey[1])
num_to_bytes(e_sector[i].Key[1], 6, block+10);
mfEmlSetMem(block, FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1, 1);
}
PrintAndLogEx(SUCCESS, "Found keys have been transferred to the emulator memory");
} }
if (createDumpFile) {
fptr = GenerateFilename("hf-mf-", "-key.bin");
if (fptr == NULL)
return 1;
fclose(fkeys); FILE *fkeys = fopen(fptr, "wb");
PrintAndLogEx(NORMAL, "Found keys have been dumped to %s --> 0xffffffffffff has been inserted for unknown keys.", fptr); 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<sectorsCnt; i++) {
num_to_bytes(e_sector[i].Key[0], 6, tempkey);
fwrite (tempkey, 1, 6, fkeys);
}
for (i=0; i<sectorsCnt; i++) {
num_to_bytes(e_sector[i].Key[1], 6, tempkey);
fwrite (tempkey, 1, 6, fkeys );
}
fclose(fkeys);
PrintAndLogEx(SUCCESS, "Found keys have been dumped to " _YELLOW_(%s)" --> 0xffffffffffff has been inserted for unknown keys.", fptr);
}
} }
free(keyBlock); free(keyBlock);
@ -1695,8 +1716,8 @@ out:
int CmdHF14AMfChk(const char *Cmd) { int CmdHF14AMfChk(const char *Cmd) {
char ctmp = param_getchar(Cmd, 0); char ctmp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) < 3 || ctmp == 'h' || ctmp == 'H') return usage_hf14_chk(); if (strlen(Cmd) < 3 || ctmp == 'h') return usage_hf14_chk();
FILE * f; FILE * f;
char filename[FILE_PATH_SIZE]={0}; char filename[FILE_PATH_SIZE]={0};
@ -1729,23 +1750,21 @@ int CmdHF14AMfChk(const char *Cmd) {
blockNo = param_get8(Cmd, 0); blockNo = param_get8(Cmd, 0);
} }
ctmp = param_getchar(Cmd, 1); ctmp = tolower(param_getchar(Cmd, 1));
clen = param_getlength(Cmd, 1); clen = param_getlength(Cmd, 1);
if (clen == 1) { if (clen == 1) {
switch (ctmp) { switch (ctmp) {
case 'a': case 'a':
case 'A':
keyType = 0; keyType = 0;
break; break;
case 'b': case 'b':
case 'B':
keyType = 1; keyType = 1;
break; break;
case '?': case '?':
keyType = 2; keyType = 2;
break; break;
default: default:
PrintAndLogEx(NORMAL, "Key type must be A , B or ?"); PrintAndLogEx(FAILED, "Key type must be A , B or ?");
free(keyBlock); free(keyBlock);
return 1; return 1;
}; };
@ -1753,7 +1772,7 @@ int CmdHF14AMfChk(const char *Cmd) {
for (i = 2; param_getchar(Cmd, i); i++) { for (i = 2; param_getchar(Cmd, i); i++) {
ctmp = param_getchar(Cmd, i); ctmp = tolower(param_getchar(Cmd, i));
clen = param_getlength(Cmd, i); clen = param_getlength(Cmd, i);
if (clen == 12) { if (clen == 12) {
@ -1775,8 +1794,8 @@ int CmdHF14AMfChk(const char *Cmd) {
PrintAndLogEx(NORMAL, "[%2d] key %s", keycnt, sprint_hex( (keyBlock + 6*keycnt), 6 ) );; PrintAndLogEx(NORMAL, "[%2d] key %s", keycnt, sprint_hex( (keyBlock + 6*keycnt), 6 ) );;
keycnt++; keycnt++;
} else if ( clen == 1 ) { } else if ( clen == 1 ) {
if (ctmp == 't' || ctmp == 'T') { transferToEml = 1; continue; } if (ctmp == 't' ) { transferToEml = 1; continue; }
if (ctmp == 'd' || ctmp == 'D') { createDumpFile = 1; continue; } if (ctmp == 'd' ) { createDumpFile = 1; continue; }
} else { } else {
// May be a dic file // May be a dic file
if ( param_getstr(Cmd, i, filename, sizeof(filename)) >= FILE_PATH_SIZE ) { if ( param_getstr(Cmd, i, filename, sizeof(filename)) >= FILE_PATH_SIZE ) {
@ -1786,7 +1805,7 @@ int CmdHF14AMfChk(const char *Cmd) {
f = fopen( filename , "r"); f = fopen( filename , "r");
if ( !f ) { if ( !f ) {
PrintAndLogEx(FAILED, "File: %s: not found or locked.", filename); PrintAndLogEx(FAILED, "File: " _YELLOW_(%s)": not found or locked.", filename);
continue; continue;
} }
@ -1801,7 +1820,7 @@ int CmdHF14AMfChk(const char *Cmd) {
// codesmell, only checks first char? // codesmell, only checks first char?
if (!isxdigit(buf[0])){ 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; continue;
} }
@ -1824,12 +1843,12 @@ int CmdHF14AMfChk(const char *Cmd) {
memset(buf, 0, sizeof(buf)); memset(buf, 0, sizeof(buf));
} }
fclose(f); fclose(f);
PrintAndLogEx(SUCCESS, "Loaded %2d keys from %s", keycnt, filename); PrintAndLogEx(SUCCESS, "Loaded %2d keys from " _YELLOW_(%s), keycnt, filename);
} }
} }
if (keycnt == 0) { 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++) for (;keycnt < MIFARE_DEFAULTKEYS_SIZE; keycnt++)
PrintAndLogEx(NORMAL, "[%2d] %02x%02x%02x%02x%02x%02x", keycnt, PrintAndLogEx(NORMAL, "[%2d] %02x%02x%02x%02x%02x%02x", keycnt,
(keyBlock + 6*keycnt)[0],(keyBlock + 6*keycnt)[1], (keyBlock + 6*keycnt)[2], (keyBlock + 6*keycnt)[0],(keyBlock + 6*keycnt)[1], (keyBlock + 6*keycnt)[2],
@ -1873,7 +1892,7 @@ int CmdHF14AMfChk(const char *Cmd) {
printf("."); fflush(stdout); printf("."); fflush(stdout);
if (ukbhit()) { if (ukbhit()) {
int gc = getchar(); (void)gc; int gc = getchar(); (void)gc;
PrintAndLogEx(NORMAL, "\naborted via keyboard!\n"); PrintAndLogEx(INFO, "\naborted via keyboard!\n");
goto out; goto out;
} }
@ -1892,12 +1911,12 @@ int CmdHF14AMfChk(const char *Cmd) {
} }
} }
t1 = msclock() - t1; 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? // 20160116 If Sector A is found, but not Sector B, try just reading it of the tag?
if ( keyType != 1 ) { if ( keyType != 1 ) {
PrintAndLogEx(NORMAL, "testing to read key B..."); PrintAndLogEx(INFO, "testing to read key B...");
for (i = 0; i < SectorsCnt; i++) { for (i = 0; i < SectorsCnt; i++) {
// KEY A but not KEY B // KEY A but not KEY B
if ( e_sector[i].foundKey[0] && !e_sector[i].foundKey[1] ) { 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); num_to_bytes(e_sector[i].Key[1], 6, block+10);
mfEmlSetMem(block, FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1, 1); 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) { if (createDumpFile) {
@ -1953,12 +1972,12 @@ out:
FILE *fkeys = fopen(fptr, "wb"); FILE *fkeys = fopen(fptr, "wb");
if (fkeys == NULL) { if (fkeys == NULL) {
PrintAndLogEx(WARNING, "Could not create file %s", fptr); PrintAndLogEx(WARNING, "Could not create file " _YELLOW_(%s), fptr);
free(keyBlock); free(keyBlock);
free(e_sector); free(e_sector);
return 1; 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<SectorsCnt; i++) { for( i=0; i<SectorsCnt; i++) {
num_to_bytes(e_sector[i].Key[0], 6, tempkey); num_to_bytes(e_sector[i].Key[0], 6, tempkey);
@ -1969,7 +1988,7 @@ out:
fwrite ( tempkey, 1, 6, fkeys ); fwrite ( tempkey, 1, 6, fkeys );
} }
fclose(fkeys); fclose(fkeys);
PrintAndLogEx(NORMAL, "Found keys have been dumped to file %s. 0xffffffffffff has been inserted for unknown keys.", fptr); PrintAndLogEx(SUCCESS, "Found keys have been dumped to file " _YELLOW_(%s)". 0xffffffffffff has been inserted for unknown keys.", fptr);
} }
free(keyBlock); free(keyBlock);
@ -2018,7 +2037,7 @@ void readerAttack(nonces_t data, bool setEmulatorMem, bool verbose) {
uint8_t sector = data.sector; uint8_t sector = data.sector;
uint8_t keytype = data.keytype; uint8_t keytype = data.keytype;
PrintAndLogEx(NORMAL, "Reader is trying authenticate with: Key %s, sector %02d: [%012" PRIx64 "]" PrintAndLogEx(INFO, "Reader is trying authenticate with: Key %s, sector %02d: [%012" PRIx64 "]"
, keytype ? "B" : "A" , keytype ? "B" : "A"
, sector , sector
, key , key
@ -2033,7 +2052,7 @@ void readerAttack(nonces_t data, bool setEmulatorMem, bool verbose) {
num_to_bytes( k_sector[sector].Key[0], 6, memBlock); num_to_bytes( k_sector[sector].Key[0], 6, memBlock);
num_to_bytes( k_sector[sector].Key[1], 6, memBlock+10); num_to_bytes( k_sector[sector].Key[1], 6, memBlock+10);
//iceman, guessing this will not work so well for 4K tags. //iceman, guessing this will not work so well for 4K tags.
PrintAndLogEx(NORMAL, "Setting Emulator Memory Block %02d: [%s]" PrintAndLogEx(INFO, "Setting Emulator Memory Block %02d: [%s]"
, (sector*4) + 3 , (sector*4) + 3
, sprint_hex( memBlock, sizeof(memBlock)) , sprint_hex( memBlock, sizeof(memBlock))
); );
@ -2108,7 +2127,7 @@ int CmdHF14AMf1kSim(const char *Cmd) {
UsbCommand resp; UsbCommand resp;
if(flags & FLAG_INTERACTIVE) { if(flags & FLAG_INTERACTIVE) {
PrintAndLogEx(NORMAL, "Press pm3-button or send another cmd to abort simulation"); PrintAndLogEx(INFO, "Press pm3-button or send another cmd to abort simulation");
while( !ukbhit() ){ while( !ukbhit() ){
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500) ) continue; if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500) ) continue;
@ -2144,8 +2163,8 @@ int CmdHF14AMfSniff(const char *Cmd){
memset(uid, 0x00, sizeof(uid)); memset(uid, 0x00, sizeof(uid));
char ctmp = param_getchar(Cmd, 0); char ctmp = tolower(param_getchar(Cmd, 0));
if ( ctmp == 'h' || ctmp == 'H' ) return usage_hf14_sniff(); if ( ctmp == 'h') return usage_hf14_sniff();
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
ctmp = tolower(param_getchar(Cmd, i)); ctmp = tolower(param_getchar(Cmd, i));
@ -2172,7 +2191,7 @@ int CmdHF14AMfSniff(const char *Cmd){
printf("."); fflush(stdout); printf("."); fflush(stdout);
if (ukbhit()) { if (ukbhit()) {
int gc = getchar(); (void)gc; int gc = getchar(); (void)gc;
PrintAndLogEx(NORMAL, "\n[!] aborted via keyboard!\n"); PrintAndLogEx(INFO, "\naborted via keyboard!\n");
break; break;
} }
@ -2195,7 +2214,7 @@ int CmdHF14AMfSniff(const char *Cmd){
if (traceLen > bufsize || buf == NULL) { if (traceLen > bufsize || buf == NULL) {
uint8_t *p; uint8_t *p;
if (buf == NULL) // not yet allocated if (buf == NULL) // not yet allocated
p = malloc(traceLen); p = calloc(traceLen, sizeof(uint8_t));
else // need more memory else // need more memory
p = realloc(buf, traceLen); p = realloc(buf, traceLen);
@ -2412,14 +2431,14 @@ int CmdHF14AMfELoad(const char *Cmd) {
return usage_hf14_eload(); return usage_hf14_eload();
switch (c) { switch (c) {
case '0' : numBlocks = 5*4; break; case '0' : numBlocks = MIFARE_MINI_MAXBLOCK; break;
case '1' : case '1' :
case '\0': numBlocks = 16*4; break; case '\0': numBlocks = MIFARE_1K_MAXBLOCK; break;
case '2' : numBlocks = 32*4; break; case '2' : numBlocks = MIFARE_2K_MAXBLOCK; break;
case '4' : numBlocks = 256; break; case '4' : numBlocks = MIFARE_4K_MAXBLOCK; break;
case 'u' : numBlocks = 255; blockWidth = 4; break; case 'u' : numBlocks = 255; blockWidth = 4; break;
default: { default: {
numBlocks = 16*4; numBlocks = MIFARE_1K_MAXBLOCK;
nameParamNo = 0; nameParamNo = 0;
} }
} }
@ -2475,7 +2494,7 @@ int CmdHF14AMfELoad(const char *Cmd) {
return 4; 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; return 0;
} }
@ -2496,14 +2515,14 @@ int CmdHF14AMfESave(const char *Cmd) {
blocks = NumOfBlocks(c); blocks = NumOfBlocks(c);
bytes = blocks * MFBLOCK_SIZE; bytes = blocks * MFBLOCK_SIZE;
dump = calloc(sizeof(uint8_t), bytes); dump = calloc(bytes, sizeof(uint8_t));
if (!dump) { if (!dump) {
PrintAndLogEx(WARNING, "Fail, cannot allocate memory"); PrintAndLogEx(WARNING, "Fail, cannot allocate memory");
return 1; return 1;
} }
memset(dump, 0, bytes); 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)) { if (!GetFromDevice( BIG_BUF_EML, dump, bytes, 0, NULL, 2500, false)) {
PrintAndLogEx(WARNING, "Fail, transfer from device time-out"); PrintAndLogEx(WARNING, "Fail, transfer from device time-out");
free(dump); free(dump);
@ -2761,7 +2780,7 @@ int CmdHF14AMfCLoad(const char *Cmd) {
blockNum++; blockNum++;
// magic card type - mifare 1K // magic card type - mifare 1K
if (blockNum >= 16 * 4) break; if (blockNum >= MIFARE_1K_MAXBLOCK ) break;
} }
PrintAndLogEx(NORMAL, "\n"); PrintAndLogEx(NORMAL, "\n");
@ -2783,8 +2802,8 @@ int CmdHF14AMfCGetBlk(const char *Cmd) {
int res; int res;
memset(data, 0x00, sizeof(data)); memset(data, 0x00, sizeof(data));
char ctmp = param_getchar(Cmd, 0); char ctmp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) < 1 || ctmp == 'h' || ctmp == 'H') return usage_hf14_cgetblk(); if (strlen(Cmd) < 1 || ctmp == 'h') return usage_hf14_cgetblk();
blockNo = param_get8(Cmd, 0); blockNo = param_get8(Cmd, 0);
@ -2819,8 +2838,8 @@ int CmdHF14AMfCGetSc(const char *Cmd) {
uint8_t sector = 0; uint8_t sector = 0;
int i, res, flags; int i, res, flags;
char ctmp = param_getchar(Cmd, 0); char ctmp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) < 1 || ctmp == 'h' || ctmp == 'H') return usage_hf14_cgetsc(); if (strlen(Cmd) < 1 || ctmp == 'h') return usage_hf14_cgetsc();
sector = param_get8(Cmd, 0); sector = param_get8(Cmd, 0);
if (sector > 39) { if (sector > 39) {
@ -2912,7 +2931,7 @@ int CmdHF14AMfCSave(const char *Cmd) {
if (errors || cmdp == 0) return usage_hf14_csave(); if (errors || cmdp == 0) return usage_hf14_csave();
dump = malloc(bytes); dump = calloc(bytes, sizeof(uint8_t));
if (!dump) { if (!dump) {
PrintAndLogEx(WARNING, "Fail, cannot allocate memory"); PrintAndLogEx(WARNING, "Fail, cannot allocate memory");
return 1; return 1;
@ -2958,8 +2977,8 @@ int CmdHF14AMfCSave(const char *Cmd) {
//needs nt, ar, at, Data to decrypt //needs nt, ar, at, Data to decrypt
int CmdHf14AMfDecryptBytes(const char *Cmd){ int CmdHf14AMfDecryptBytes(const char *Cmd){
char ctmp = param_getchar(Cmd, 0); char ctmp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) < 1 || ctmp == 'h' || ctmp == 'H') return usage_hf14_decryptbytes(); if (strlen(Cmd) < 1 || ctmp == 'h') return usage_hf14_decryptbytes();
uint32_t nt = param_get32ex(Cmd,0,0,16); uint32_t nt = param_get32ex(Cmd,0,0,16);
uint32_t ar_enc = param_get32ex(Cmd,1,0,16); uint32_t ar_enc = param_get32ex(Cmd,1,0,16);
@ -3010,7 +3029,7 @@ int CmdHf14AMfSetMod(const char *Cmd) {
UsbCommand resp; UsbCommand resp;
if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
uint8_t ok = resp.arg[0] & 0xff; uint8_t ok = resp.arg[0] & 0xff;
PrintAndLogEx(NORMAL, "isOk:%02x", ok); PrintAndLogEx(SUCCESS, "isOk:%02x", ok);
if (!ok) if (!ok)
PrintAndLogEx(FAILED, "Failed."); PrintAndLogEx(FAILED, "Failed.");
} else { } else {
@ -3023,12 +3042,12 @@ int CmdHf14AMfSetMod(const char *Cmd) {
int CmdHf14AMfNack(const char *Cmd) { int CmdHf14AMfNack(const char *Cmd) {
bool verbose = false; bool verbose = false;
char ctmp = param_getchar(Cmd, 0); char ctmp = tolower(param_getchar(Cmd, 0));
if ( ctmp == 'h' || ctmp == 'H' ) return usage_hf14_nack(); if ( ctmp == 'h' ) return usage_hf14_nack();
if ( ctmp == 'v' || ctmp == 'V' ) verbose = true; if ( ctmp == 'v' ) verbose = true;
if ( verbose ) 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); detect_classic_nackbug(verbose);
return 0; return 0;
@ -3086,7 +3105,7 @@ int CmdHF14AMfice(const char *Cmd) {
PrintAndLogEx(NORMAL, "Collecting %u nonces \n", limit); PrintAndLogEx(NORMAL, "Collecting %u nonces \n", limit);
if ((fnonces = fopen(filename,"wb")) == NULL) { 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; return 3;
} }
@ -3097,7 +3116,7 @@ int CmdHF14AMfice(const char *Cmd) {
do { do {
if (ukbhit()) { if (ukbhit()) {
int gc = getchar(); (void)gc; int gc = getchar(); (void)gc;
PrintAndLogEx(NORMAL, "\naborted via keyboard!\n"); PrintAndLogEx(INFO, "\naborted via keyboard!\n");
break; break;
} }
@ -3119,7 +3138,7 @@ int CmdHF14AMfice(const char *Cmd) {
total_num_nonces += items; total_num_nonces += items;
if ( total_num_nonces > part_limit ) { 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; part_limit += 3000;
} }
@ -3130,7 +3149,7 @@ int CmdHF14AMfice(const char *Cmd) {
} while (!acquisition_completed); } while (!acquisition_completed);
out: out:
PrintAndLogEx(NORMAL, "time: %" PRIu64 " seconds\n", (msclock()-t1)/1000); PrintAndLogEx(SUCCESS, "time: %" PRIu64 " seconds\n", (msclock()-t1)/1000);
if ( fnonces ) { if ( fnonces ) {
fflush(fnonces); fflush(fnonces);

View file

@ -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) 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); *brute_forces = MIN(brute_forces1, brute_forces2);
float reduction_rate = update_reduction_rate(*brute_forces, false); 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));
} }

View file

@ -980,11 +980,11 @@ int CmdHF14AMfUInfo(const char *Cmd){
if ( hasAuthKey ) return 1; if ( hasAuthKey ) return 1;
// also try to diversify default keys.. look into CmdHF14AMfuGenDiverseKeys // 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 ) { for (uint8_t i = 0; i < KEYS_3DES_COUNT; ++i ) {
key = default_3des_keys[i]; key = default_3des_keys[i];
if (ulc_authentication(key, true)) { if (ulc_authentication(key, true)) {
PrintAndLogEx(NORMAL, "Found default 3des key: "); PrintAndLogEx(SUCCESS, "Found default 3des key: ");
uint8_t keySwap[16]; uint8_t keySwap[16];
memcpy(keySwap, SwapEndian64(key,16,8), 16); memcpy(keySwap, SwapEndian64(key,16,8), 16);
ulc_print_3deskey(keySwap); ulc_print_3deskey(keySwap);
@ -1079,7 +1079,7 @@ int CmdHF14AMfUInfo(const char *Cmd){
num_to_bytes( ul_ev1_pwdgenA(card.uid), 4, key); num_to_bytes( ul_ev1_pwdgenA(card.uid), 4, key);
len = ulev1_requestAuthentication(key, pack, sizeof(pack)); len = ulev1_requestAuthentication(key, pack, sizeof(pack));
if (len > -1) { 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; goto out;
} }
@ -1089,7 +1089,7 @@ int CmdHF14AMfUInfo(const char *Cmd){
num_to_bytes( ul_ev1_pwdgenB(card.uid), 4, key); num_to_bytes( ul_ev1_pwdgenB(card.uid), 4, key);
len = ulev1_requestAuthentication(key, pack, sizeof(pack)); len = ulev1_requestAuthentication(key, pack, sizeof(pack));
if (len > -1) { 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; goto out;
} }
@ -1099,7 +1099,7 @@ int CmdHF14AMfUInfo(const char *Cmd){
num_to_bytes( ul_ev1_pwdgenC(card.uid), 4, key); num_to_bytes( ul_ev1_pwdgenC(card.uid), 4, key);
len = ulev1_requestAuthentication(key, pack, sizeof(pack)); len = ulev1_requestAuthentication(key, pack, sizeof(pack));
if (len > -1) { 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; goto out;
} }
@ -1109,7 +1109,7 @@ int CmdHF14AMfUInfo(const char *Cmd){
num_to_bytes( ul_ev1_pwdgenD(card.uid), 4, key); num_to_bytes( ul_ev1_pwdgenD(card.uid), 4, key);
len = ulev1_requestAuthentication(key, pack, sizeof(pack)); len = ulev1_requestAuthentication(key, pack, sizeof(pack));
if (len > -1) { 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; goto out;
} }
@ -1119,13 +1119,13 @@ int CmdHF14AMfUInfo(const char *Cmd){
key = default_pwd_pack[i]; key = default_pwd_pack[i];
len = ulev1_requestAuthentication(key, pack, sizeof(pack)); len = ulev1_requestAuthentication(key, pack, sizeof(pack));
if (len > -1) { 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; break;
} else { } else {
if (!ul_auth_select( &card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack))) return -1; 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: out:
@ -1250,7 +1250,7 @@ int CmdHF14AMfUWrBl(const char *Cmd){
UsbCommand resp; UsbCommand resp;
if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
uint8_t isOK = resp.arg[0] & 0xff; uint8_t isOK = resp.arg[0] & 0xff;
PrintAndLogEx(NORMAL, "isOk:%02x", isOK); PrintAndLogEx(SUCCESS, "isOk:%02x", isOK);
} else { } else {
PrintAndLogEx(WARNING, "Command execute timeout"); PrintAndLogEx(WARNING, "Command execute timeout");
} }
@ -1365,7 +1365,7 @@ int CmdHF14AMfURdBl(const char *Cmd){
PrintAndLogEx(WARNING, "Failed reading block: (%02x)", isOK); PrintAndLogEx(WARNING, "Failed reading block: (%02x)", isOK);
} }
} else { } else {
PrintAndLogEx(NORMAL, "Command execute time-out"); PrintAndLogEx(WARNING, "Command execute time-out");
} }
return 0; return 0;
} }
@ -1743,7 +1743,7 @@ int CmdHF14AMfUDump(const char *Cmd){
} }
} }
ul_print_type(tagtype, 0); ul_print_type(tagtype, 0);
PrintAndLogEx(NORMAL, "Reading tag memory..."); PrintAndLogEx(SUCCESS, "Reading tag memory...");
UsbCommand c = {CMD_MIFAREU_READCARD, {startPage, pages}}; UsbCommand c = {CMD_MIFAREU_READCARD, {startPage, pages}};
if ( hasAuthKey ) { if ( hasAuthKey ) {
if (tagtype & UL_C) if (tagtype & UL_C)
@ -1912,12 +1912,10 @@ int CmdHF14AMfURestore(const char *Cmd){
memset(authkey, 0x00, sizeof(authkey)); memset(authkey, 0x00, sizeof(authkey));
while(param_getchar(Cmd, cmdp) != 0x00 && !errors) { while(param_getchar(Cmd, cmdp) != 0x00 && !errors) {
switch(param_getchar(Cmd, cmdp)) { switch (tolower(param_getchar(Cmd, cmdp))) {
case 'h': case 'h':
case 'H':
return usage_hf_mfu_restore(); return usage_hf_mfu_restore();
case 'k': case 'k':
case 'K':
keylen = param_getstr(Cmd, cmdp+1, tempStr, sizeof(tempStr)); keylen = param_getstr(Cmd, cmdp+1, tempStr, sizeof(tempStr));
if (keylen == 32 || keylen == 8) { //ul-c or ev1/ntag key length if (keylen == 32 || keylen == 8) { //ul-c or ev1/ntag key length
errors = param_gethex(tempStr, 0, authkey, keylen); errors = param_gethex(tempStr, 0, authkey, keylen);
@ -1930,12 +1928,10 @@ int CmdHF14AMfURestore(const char *Cmd){
hasKey = true; hasKey = true;
break; break;
case 'l': case 'l':
case 'L':
swapEndian = true; swapEndian = true;
cmdp++; cmdp++;
break; break;
case 'f': case 'f':
case 'F':
filelen = param_getstr(Cmd, cmdp+1, filename, FILE_PATH_SIZE); filelen = param_getstr(Cmd, cmdp+1, filename, FILE_PATH_SIZE);
if (filelen > FILE_PATH_SIZE-5) if (filelen > FILE_PATH_SIZE-5)
@ -1947,17 +1943,14 @@ int CmdHF14AMfURestore(const char *Cmd){
cmdp += 2; cmdp += 2;
break; break;
case 's': case 's':
case 'S':
cmdp++; cmdp++;
write_special = true; write_special = true;
break; break;
case 'e': case 'e':
case 'E':
cmdp++; cmdp++;
write_extra = true; write_extra = true;
break; break;
case 'r': case 'r':
case 'R':
cmdp++; cmdp++;
read_key = true; read_key = true;
break; break;
@ -1972,7 +1965,7 @@ int CmdHF14AMfURestore(const char *Cmd){
if (errors || cmdp == 0) return usage_hf_mfu_restore(); if (errors || cmdp == 0) return usage_hf_mfu_restore();
if ((f = fopen(filename,"rb")) == NULL) { 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; return 1;
} }
@ -2000,7 +1993,7 @@ int CmdHF14AMfURestore(const char *Cmd){
return 1; 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; mfu_dump_t *mem = (mfu_dump_t*)dump;
uint8_t pages = (bytes_read-48)/4; 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 // write all other data
// Skip block 0,1,2,3 (only magic tags can write to them) // Skip block 0,1,2,3 (only magic tags can write to them)
// Skip last 5 blocks usually is configuration // Skip last 5 blocks usually is configuration
@ -2103,7 +2096,7 @@ int CmdHF14AMfURestore(const char *Cmd){
// write special data last // write special data last
if (write_special) { 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)); 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 // Load emulator with dump file
// //
int CmdHF14AMfUeLoad(const char *Cmd){ int CmdHF14AMfUeLoad(const char *Cmd){
char c = param_getchar(Cmd, 0); char c = tolower(param_getchar(Cmd, 0));
if ( c == 'h' || c == 'H' || c == 0x00) return usage_hf_mfu_eload(); if ( c == 'h' || c == 0x00) return usage_hf_mfu_eload();
return CmdHF14AMfELoad(Cmd); return CmdHF14AMfELoad(Cmd);
} }
// //
// Simulate tag // Simulate tag
// //
int CmdHF14AMfUSim(const char *Cmd){ int CmdHF14AMfUSim(const char *Cmd){
char c = param_getchar(Cmd, 0); char c = tolower(param_getchar(Cmd, 0));
if ( c == 'h' || c == 'H' || c == 0x00) return usage_hf_mfu_sim(); if ( c == 'h' || c == 0x00) return usage_hf_mfu_sim();
return CmdHF14ASim(Cmd); return CmdHF14ASim(Cmd);
} }
@ -2153,16 +2146,16 @@ int CmdHF14AMfucAuth(const char *Cmd){
uint8_t keyNo = 3; uint8_t keyNo = 3;
bool errors = false; bool errors = false;
char cmdp = param_getchar(Cmd, 0); char cmdp = tolower(param_getchar(Cmd, 0));
//Change key to user defined one //Change key to user defined one
if (cmdp == 'k' || cmdp == 'K'){ if (cmdp == 'k'){
keyNo = param_get8(Cmd, 1); keyNo = param_get8(Cmd, 1);
if(keyNo >= KEYS_3DES_COUNT) if(keyNo >= KEYS_3DES_COUNT)
errors = true; errors = true;
} }
if (cmdp == 'h' || cmdp == 'H') errors = true; if (cmdp == 'h') errors = true;
if (errors) return usage_hf_mfu_ucauth(); if (errors) return usage_hf_mfu_ucauth();
@ -2278,9 +2271,9 @@ int CmdTestDES(const char * cmd)
int CmdHF14AMfucSetPwd(const char *Cmd){ int CmdHF14AMfucSetPwd(const char *Cmd){
uint8_t pwd[16] = {0x00}; 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)) { if (param_gethex(Cmd, 0, pwd, 32)) {
PrintAndLogEx(WARNING, "Password must include 32 HEX symbols"); PrintAndLogEx(WARNING, "Password must include 32 HEX symbols");
@ -2295,7 +2288,7 @@ int CmdHF14AMfucSetPwd(const char *Cmd){
UsbCommand resp; UsbCommand resp;
if (WaitForResponseTimeout(CMD_ACK,&resp,1500) ) { if (WaitForResponseTimeout(CMD_ACK,&resp,1500) ) {
if ( (resp.arg[0] & 0xff) == 1) { 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 { } else {
PrintAndLogEx(WARNING, "Failed writing at block %d", resp.arg[1] & 0xff); PrintAndLogEx(WARNING, "Failed writing at block %d", resp.arg[1] & 0xff);
return 1; return 1;
@ -2315,9 +2308,9 @@ int CmdHF14AMfucSetUid(const char *Cmd){
UsbCommand c = {CMD_MIFAREU_READBL}; UsbCommand c = {CMD_MIFAREU_READBL};
UsbCommand resp; UsbCommand resp;
uint8_t uid[7] = {0x00}; 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)) { if (param_gethex(Cmd, 0, uid, 14)) {
PrintAndLogEx(WARNING, "UID must include 14 HEX symbols"); PrintAndLogEx(WARNING, "UID must include 14 HEX symbols");

View file

@ -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); 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; uint16_t memsize = (data[2] + 1) * 8;
topaz_tag.size = memsize; 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: Physical Memory Size of this tag: %d bytes", data[2], memsize);
PrintAndLogEx(NORMAL, " %02x: %s / %s", data[3], PrintAndLogEx(NORMAL, " %02x: %s / %s", data[3],
(data[3] & 0xF0) ? "(RFU)" : "Read access granted without any security", (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 *old = topaz_tag.dynamic_lock_areas;
dynamic_lock_area_t *new = topaz_tag.dynamic_lock_areas; dynamic_lock_area_t *new = topaz_tag.dynamic_lock_areas;
if (old == NULL) { 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 { } else {
while(old->next != NULL) { while(old->next != NULL) {
old = old->next; 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; new->next = NULL;
if (area_start <= next_lockable_byte) { if (area_start <= next_lockable_byte) {

View file

@ -257,9 +257,9 @@ int CmdVersion(const char *Cmd) {
SendCommand(&c); SendCommand(&c);
if (WaitForResponseTimeout(CMD_ACK, &resp, 1000)) { if (WaitForResponseTimeout(CMD_ACK, &resp, 1000)) {
#ifdef __WIN32 #ifdef __WIN32
PrintAndLogEx(NORMAL, "\nProxmark3 RFID instrument\n"); PrintAndLogEx(NORMAL, "\n [ Proxmark3 RFID instrument ]\n");
#else #else
PrintAndLogEx(NORMAL, "\n\e[34mProxmark3 RFID instrument\e[0m\n"); PrintAndLogEx(NORMAL, "\n\e[34m [ Proxmark3 RFID instrument ]\e[0m\n");
#endif #endif
char s[50] = {0}; char s[50] = {0};
#if defined(WITH_FLASH) || defined(WITH_SMARTCARD) || defined(WITH_FPC) #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); strncat(s, "fpc; ", sizeof(s) - strlen(s) - 1);
#endif #endif
PrintAndLogEx(NORMAL, "\n [ CLIENT ]"); PrintAndLogEx(NORMAL, "\n [ CLIENT ]");
PrintAndLogEx(NORMAL, " client: iceman %s \n", s); PrintAndLogEx(NORMAL, " client: iceman %s \n", s);
PrintAndLogEx(NORMAL, (char*)resp.d.asBytes); PrintAndLogEx(NORMAL, (char*)resp.d.asBytes);
lookupChipID(resp.arg[0], resp.arg[1]); lookupChipID(resp.arg[0], resp.arg[1]);

View file

@ -141,21 +141,33 @@ int usage_t55xx_wakup(){
PrintAndLogEx(NORMAL, " lf t55xx wakeup p 11223344 - send wakeup password"); PrintAndLogEx(NORMAL, " lf t55xx wakeup p 11223344 - send wakeup password");
return 0; return 0;
} }
int usage_t55xx_bruteforce(){ int usage_t55xx_chk(){
PrintAndLogEx(NORMAL, "This command uses A) bruteforce to scan a number range"); PrintAndLogEx(NORMAL, "This command uses a dictionary attack");
PrintAndLogEx(NORMAL, " B) a dictionary attack");
PrintAndLogEx(NORMAL, "press 'enter' to cancel the command"); PrintAndLogEx(NORMAL, "press 'enter' to cancel the command");
PrintAndLogEx(NORMAL, "Usage: lf t55xx bruteforce [h] <start password> <end password> [i <*.dic>]"); PrintAndLogEx(NORMAL, "Usage: lf t55xx bruteforce [h] <m> [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] <start password> <end password>");
PrintAndLogEx(NORMAL, " password must be 4 bytes (8 hex symbols)"); PrintAndLogEx(NORMAL, " password must be 4 bytes (8 hex symbols)");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h - this help"); PrintAndLogEx(NORMAL, " h - this help");
PrintAndLogEx(NORMAL, " <start_pwd> - 4 byte hex value to start pwd search at"); PrintAndLogEx(NORMAL, " <start_pwd> - 4 byte hex value to start pwd search at");
PrintAndLogEx(NORMAL, " <end_pwd> - 4 byte hex value to end pwd search at"); PrintAndLogEx(NORMAL, " <end_pwd> - 4 byte hex value to end pwd search at");
PrintAndLogEx(NORMAL, " i <*.dic> - loads a default keys dictionary file <*.dic>");
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, " lf t55xx bruteforce aaaaaaaa bbbbbbbb"); PrintAndLogEx(NORMAL, " lf t55xx bruteforce aaaaaaaa bbbbbbbb");
PrintAndLogEx(NORMAL, " lf t55xx bruteforce i default_pwd.dic");
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
return 0; return 0;
} }
@ -224,10 +236,9 @@ int CmdT55xxSetConfig(const char *Cmd) {
uint8_t cmdp = 0; uint8_t cmdp = 0;
bool errors = false; bool errors = false;
while(param_getchar(Cmd, cmdp) != 0x00 && !errors) { while(param_getchar(Cmd, cmdp) != 0x00 && !errors) {
tmp = param_getchar(Cmd, cmdp); tmp = tolower(param_getchar(Cmd, cmdp));
switch(tmp) { switch(tmp) {
case 'h': case 'h':
case 'H':
return usage_t55xx_config(); return usage_t55xx_config();
case 'b': case 'b':
errors |= param_getdec(Cmd, cmdp+1, &bitRate); errors |= param_getdec(Cmd, cmdp+1, &bitRate);
@ -292,12 +303,10 @@ int CmdT55xxSetConfig(const char *Cmd) {
config.offset = offset; config.offset = offset;
cmdp+=2; cmdp+=2;
break; break;
case 'Q':
case 'q': case 'q':
config.Q5 = true; config.Q5 = true;
cmdp++; cmdp++;
break; break;
case 'S':
case 's': case 's':
config.ST = true; config.ST = true;
cmdp++; 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 (!AquireData(page1, block, usepwd, password) ) return 0;
if (!DecodeT55xxBlock()) return 0; if (!DecodeT55xxBlock()) return 0;
char blk[10]={0}; char blk[10] = {0};
sprintf(blk,"%02d", block); sprintf(blk, "%02d", block);
printT55xxBlock(blk); printT55xxBlock(blk);
return 1; return 1;
} }
@ -358,22 +367,18 @@ int CmdT55xxReadBlock(const char *Cmd) {
bool errors = false; bool errors = false;
uint8_t cmdp = 0; uint8_t cmdp = 0;
while(param_getchar(Cmd, cmdp) != 0x00 && !errors) { while(param_getchar(Cmd, cmdp) != 0x00 && !errors) {
switch(param_getchar(Cmd, cmdp)) { switch ( tolower(param_getchar(Cmd, cmdp))) {
case 'h': case 'h':
case 'H':
return usage_t55xx_read(); return usage_t55xx_read();
case 'b': case 'b':
case 'B':
errors |= param_getdec(Cmd, cmdp+1, &block); errors |= param_getdec(Cmd, cmdp+1, &block);
cmdp += 2; cmdp += 2;
break; break;
case 'o': case 'o':
case 'O':
override = true; override = true;
cmdp++; cmdp++;
break; break;
case 'p': case 'p':
case 'P':
password = param_get32ex(Cmd, cmdp+1, 0, 16); password = param_get32ex(Cmd, cmdp+1, 0, 16);
usepwd = true; usepwd = true;
cmdp += 2; cmdp += 2;
@ -1503,23 +1508,68 @@ bool IsCancelled(void) {
return false; return false;
} }
int CmdT55xxBruteForce(const char *Cmd) { int CmdT55xxChkPwds(const char *Cmd) {
// load a default pwd file. // load a default pwd file.
char line[9]; char line[9];
char filename[FILE_PATH_SIZE] = {0}; char filename[FILE_PATH_SIZE] = {0};
int keycnt = 0; int keycnt = 0;
uint8_t stKeyBlock = 20; uint8_t stKeyBlock = 20;
uint8_t *keyBlock = NULL, *p = NULL; uint8_t *keyBlock = NULL, *p = NULL;
uint32_t start_password = 0x00000000; //start password
uint32_t end_password = 0xFFFFFFFF; //end password
bool found = false; bool found = false;
uint8_t timeout = 0;
memset(line, 0, sizeof(line)); memset(line, 0, sizeof(line));
char cmdp = tolower(param_getchar(Cmd, 0)); 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); keyBlock = calloc(stKeyBlock, 4);
if (keyBlock == NULL) return 1; if (keyBlock == NULL) return 1;
@ -1531,7 +1581,7 @@ int CmdT55xxBruteForce(const char *Cmd) {
FILE * f = fopen( filename , "r"); FILE * f = fopen( filename , "r");
if ( !f ) { if ( !f ) {
PrintAndLogEx(NORMAL, "File: %s: not found or locked.", filename); PrintAndLogEx(WARNING, "File: %s: not found or locked.", filename);
free(keyBlock); free(keyBlock);
return 1; return 1;
} }
@ -1546,7 +1596,7 @@ int CmdT55xxBruteForce(const char *Cmd) {
if( line[0]=='#' ) continue; if( line[0]=='#' ) continue;
if (!isxdigit(line[0])) { 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; continue;
} }
@ -1569,7 +1619,7 @@ int CmdT55xxBruteForce(const char *Cmd) {
num_to_bytes( strtoll(line, NULL, 16), 4, keyBlock + 4*keycnt); 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++; keycnt++;
memset(line, 0, sizeof(line)); memset(line, 0, sizeof(line));
} }
@ -1577,11 +1627,11 @@ int CmdT55xxBruteForce(const char *Cmd) {
fclose(f); fclose(f);
if (keycnt == 0) { if (keycnt == 0) {
PrintAndLogEx(NORMAL, "No keys found in file"); PrintAndLogEx(WARNING, "No keys found in file");
free(keyBlock); free(keyBlock);
return 1; return 1;
} }
PrintAndLogEx(NORMAL, "Loaded %d keys", keycnt); PrintAndLogEx(SUCCESS, "Loaded %d keys", keycnt);
// loop // loop
uint64_t testpwd = 0x00; uint64_t testpwd = 0x00;
@ -1600,69 +1650,87 @@ int CmdT55xxBruteForce(const char *Cmd) {
testpwd = bytes_to_num(keyBlock + 4*c, 4); 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)) { 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); free(keyBlock);
return 0; return 0;
} }
found = tryDetectModulation(); found = tryDetectModulation();
if ( found ) { if ( found )
PrintAndLogEx(NORMAL, "Found valid password: [%08X]", testpwd); break;
//free(keyBlock);
//return 0;
}
} }
PrintAndLogEx(NORMAL, "Password NOT found."); if ( found )
free(keyBlock); PrintAndLogEx(SUCCESS, "Found valid password: [ %08X ]", testpwd);
return 0; 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 :) // Try to read Block 7, first :)
// incremental pwd range search // incremental pwd range search
start_password = param_get32ex(Cmd, 0, 0, 16); start_password = param_get32ex(Cmd, 0, 0, 16);
end_password = param_get32ex(Cmd, 1, 0, 16); end_password = param_get32ex(Cmd, 1, 0, 16);
curr = start_password;
if ( start_password >= end_password ) { if ( start_password >= end_password ) {
free(keyBlock);
return usage_t55xx_bruteforce(); return usage_t55xx_bruteforce();
} }
PrintAndLogEx(NORMAL, "Search password range [%08X -> %08X]", start_password, end_password); PrintAndLogEx(INFO, "Search password range [%08X -> %08X]", start_password, end_password);
uint32_t i = start_password;
while ((!found) && (i <= end_password)){ while ((!found) || (curr <= end_password)){
printf("."); fflush(stdout); printf("."); fflush(stdout);
if (IsCancelled()) { if (IsCancelled()) {
free(keyBlock);
return 0; return 0;
} }
if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, i)) { if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, curr)) {
PrintAndLogEx(NORMAL, "Aquireing data from device failed. Quitting"); PrintAndLogEx(WARNING, "Aquireing data from device failed. Quitting");
free(keyBlock);
return 0; return 0;
} }
found = tryDetectModulation(); found = tryDetectModulation();
if (found) break; if (found) break;
i++; ++curr;
} }
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
if (found) if (found)
PrintAndLogEx(NORMAL, "Found valid password: [%08x]", i); PrintAndLogEx(SUCCESS, "Found valid password: [ %08X ]", curr);
else 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; return 0;
} }
@ -1746,9 +1814,9 @@ int CmdT55xxRecoverPW(const char *Cmd) {
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
if (found == 1) if (found == 1)
PrintAndLogEx(NORMAL, "Found valid password: [%08x]", curr_password); PrintAndLogEx(SUCCESS, "Found valid password: [%08x]", curr_password);
else else
PrintAndLogEx(NORMAL, "Password NOT found."); PrintAndLogEx(WARNING, "Password NOT found.");
return 0; return 0;
} }
@ -1959,6 +2027,7 @@ static command_t CommandTable[] = {
{"help", CmdHelp, 1, "This help"}, {"help", CmdHelp, 1, "This help"},
{"bruteforce", CmdT55xxBruteForce,0, "<start password> <end password> [i <*.dic>] Simple bruteforce attack to find password"}, {"bruteforce", CmdT55xxBruteForce,0, "<start password> <end password> [i <*.dic>] Simple bruteforce attack to find password"},
{"config", CmdT55xxSetConfig, 1, "Set/Get T55XX configuration (modulation, inverted, offset, rate)"}, {"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."}, {"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"}, {"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"}, {"p1detect", CmdT55xxDetectPage1,1, "[1] Try detecting if this is a t55xx tag by reading page 1"},

View file

@ -133,6 +133,7 @@ t55xx_conf_block_t Get_t55xx_Config(void);
void Set_t55xx_Config(t55xx_conf_block_t conf); void Set_t55xx_Config(t55xx_conf_block_t conf);
extern int CmdLFT55XX(const char *Cmd); extern int CmdLFT55XX(const char *Cmd);
extern int CmdT55xxChk(const char *Cmd);
extern int CmdT55xxBruteForce(const char *Cmd); extern int CmdT55xxBruteForce(const char *Cmd);
extern int CmdT55xxSetConfig(const char *Cmd); extern int CmdT55xxSetConfig(const char *Cmd);
extern int CmdT55xxReadBlock(const char *Cmd); extern int CmdT55xxReadBlock(const char *Cmd);

View file

@ -356,7 +356,7 @@ static int smart_responseEx(uint8_t *data, bool silent) {
if (needGetData) { if (needGetData) {
int len = data[datalen - 1]; int len = data[datalen - 1];
if (!silent) PrintAndLogEx(INFO, "Requesting 0x%02X bytes response", len); 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}}; UsbCommand cStatus = {CMD_SMART_RAW, {SC_RAW, sizeof(getstatus), 0}};
memcpy(cStatus.d.asBytes, getstatus, sizeof(getstatus) ); memcpy(cStatus.d.asBytes, getstatus, sizeof(getstatus) );
clearCommandBuffer(); clearCommandBuffer();
@ -372,7 +372,7 @@ static int smart_responseEx(uint8_t *data, bool silent) {
if (datalen != len + 2) { if (datalen != len + 2) {
// data with ACK // data with ACK
if (datalen == len + 2 + 1) { // 2 - response, 1 - ACK if (datalen == len + 2 + 1) { // 2 - response, 1 - ACK
if (data[0] != ISO7816_GETSTATUS) { if (data[0] != ISO7816_GET_RESPONSE) {
if (!silent) { if (!silent) {
PrintAndLogEx(ERR, "GetResponse ACK error. len 0x%x | data[0] %02X", len, data[0]); 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; json_t *root = NULL;
smart_loadjson("aidlist", "json", &root); 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 ) if ( !buf )
return 1; return 1;

View file

@ -711,4 +711,47 @@ FD8705E721B0,
00ada2cd516d, 00ada2cd516d,
# #
# #
D3F7D3F7D3F7 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,

View file

@ -96,6 +96,7 @@ FABADA11, //china?
69696969, 69696969,
12121212, 12121212,
12344321, 12344321,
1234ABCD,
11112222, 11112222,
13131313, 13131313,
10041004, 10041004,
@ -104,8 +105,8 @@ FABADA11, //china?
abcd1234, abcd1234,
20002000, 20002000,
19721972, 19721972,
aa55aa55, //amiboo aa55aa55, // amiboo
55aa55aa, //rev amiboo 55aa55aa, // rev amiboo
4f271149, // seeds ul-ev1 4f271149, // seeds ul-ev1
07d7bb0b, // seeds ul-ev1 07d7bb0b, // seeds ul-ev1
9636ef8f, // seeds ul-ev1 9636ef8f, // seeds ul-ev1
@ -113,4 +114,4 @@ b5f44686, // seeds ul-ev1
9E3779B9, // TEA 9E3779B9, // TEA
C6EF3720, // TEA C6EF3720, // TEA
7854794A, // xbox tea constant :) 7854794A, // xbox tea constant :)
F1EA5EED, //burtle F1EA5EED, // burtle

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -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,

View file

@ -623,7 +623,7 @@ int CmdEMVInternalAuthenticate(const char *cmd) {
return 0; 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) { 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 // Destroy TLV's
free(pdol_data_tlv); free(pdol_data_tlv);
@ -1346,7 +1346,7 @@ int CmdEMVScan(const char *cmd) {
} }
// drop field at start // drop field at start
DropField(); DropFieldEx( channel );
// iso 14443 select // iso 14443 select
PrintAndLogEx(NORMAL, "--> GET UID, ATS."); PrintAndLogEx(NORMAL, "--> GET UID, ATS.");
@ -1399,7 +1399,7 @@ int CmdEMVScan(const char *cmd) {
if (EMVSearch(channel, false, true, decodeTLV, tlvSelect)) { if (EMVSearch(channel, false, true, decodeTLV, tlvSelect)) {
PrintAndLogEx(ERR, "Can't found any of EMV AID. Exit..."); PrintAndLogEx(ERR, "Can't found any of EMV AID. Exit...");
tlvdb_free(tlvSelect); tlvdb_free(tlvSelect);
DropField(); DropFieldEx( channel );
return 3; return 3;
} }
@ -1415,7 +1415,7 @@ int CmdEMVScan(const char *cmd) {
if (!AIDlen) { if (!AIDlen) {
PrintAndLogEx(INFO, "Can't select AID. EMV AID not found. Exit..."); PrintAndLogEx(INFO, "Can't select AID. EMV AID not found. Exit...");
DropField(); DropFieldEx( channel );
return 4; return 4;
} }
@ -1434,7 +1434,7 @@ int CmdEMVScan(const char *cmd) {
if (res) { if (res) {
PrintAndLogEx(ERR, "Can't select AID (%d). Exit...", res); PrintAndLogEx(ERR, "Can't select AID (%d). Exit...", res);
tlvdb_free(tlvRoot); tlvdb_free(tlvRoot);
DropField(); DropFieldEx( channel );
return 5; return 5;
} }
@ -1462,7 +1462,7 @@ int CmdEMVScan(const char *cmd) {
if (!pdol_data_tlv){ if (!pdol_data_tlv){
PrintAndLogEx(ERR, "Can't create PDOL TLV."); PrintAndLogEx(ERR, "Can't create PDOL TLV.");
tlvdb_free(tlvRoot); tlvdb_free(tlvRoot);
DropField(); DropFieldEx( channel );
return 6; return 6;
} }
@ -1471,7 +1471,7 @@ int CmdEMVScan(const char *cmd) {
if (!pdol_data_tlv_data) { if (!pdol_data_tlv_data) {
PrintAndLogEx(ERR, "Can't create PDOL data."); PrintAndLogEx(ERR, "Can't create PDOL data.");
tlvdb_free(tlvRoot); tlvdb_free(tlvRoot);
DropField(); DropFieldEx( channel );
return 6; return 6;
} }
PrintAndLogEx(INFO, "PDOL data[%d]: %s", pdol_data_tlv_data_len, sprint_hex(pdol_data_tlv_data, pdol_data_tlv_data_len)); 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) { if (res) {
PrintAndLogEx(ERR, "GPO error(%d): %4x. Exit...", res, sw); PrintAndLogEx(ERR, "GPO error(%d): %4x. Exit...", res, sw);
tlvdb_free(tlvRoot); tlvdb_free(tlvRoot);
DropField(); DropFieldEx( channel );
return 7; return 7;
} }
ProcessGPOResponseFormat1(tlvRoot, buf, len, decodeTLV); ProcessGPOResponseFormat1(tlvRoot, buf, len, decodeTLV);
@ -1577,8 +1577,7 @@ int CmdEMVScan(const char *cmd) {
// free tlv object // free tlv object
tlvdb_free(tlvRoot); tlvdb_free(tlvRoot);
// DropField DropFieldEx( channel );
DropField();
res = json_dump_file(root, fname, JSON_INDENT(2)); res = json_dump_file(root, fname, JSON_INDENT(2));
if (res) { if (res) {
@ -1631,6 +1630,14 @@ int CmdEMVRoca(const char *cmd) {
if (arg_get_lit(2)) if (arg_get_lit(2))
channel = ECC_CONTACT; channel = ECC_CONTACT;
PrintChannel(channel); 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 // select card
uint8_t psenum = (channel == ECC_CONTACT) ? 1 : 2; uint8_t psenum = (channel == ECC_CONTACT) ? 1 : 2;
@ -1654,7 +1661,7 @@ int CmdEMVRoca(const char *cmd) {
if (EMVSearch(channel, false, true, false, tlvSelect)) { if (EMVSearch(channel, false, true, false, tlvSelect)) {
PrintAndLogEx(ERR, "Can't found any of EMV AID. Exit..."); PrintAndLogEx(ERR, "Can't found any of EMV AID. Exit...");
tlvdb_free(tlvSelect); tlvdb_free(tlvSelect);
DropField(); DropFieldEx( channel );
return 3; return 3;
} }
@ -1670,7 +1677,7 @@ int CmdEMVRoca(const char *cmd) {
if (!AIDlen) { if (!AIDlen) {
PrintAndLogEx(INFO, "Can't select AID. EMV AID not found. Exit..."); PrintAndLogEx(INFO, "Can't select AID. EMV AID not found. Exit...");
DropField(); DropFieldEx( channel );
return 4; return 4;
} }
@ -1685,7 +1692,7 @@ int CmdEMVRoca(const char *cmd) {
if (res) { if (res) {
PrintAndLogEx(ERR, "Can't select AID (%d). Exit...", res); PrintAndLogEx(ERR, "Can't select AID (%d). Exit...", res);
tlvdb_free(tlvRoot); tlvdb_free(tlvRoot);
DropField(); DropFieldEx( channel );
return 5; return 5;
} }
@ -1697,7 +1704,7 @@ int CmdEMVRoca(const char *cmd) {
if (!pdol_data_tlv){ if (!pdol_data_tlv){
PrintAndLogEx(ERR, "Can't create PDOL TLV."); PrintAndLogEx(ERR, "Can't create PDOL TLV.");
tlvdb_free(tlvRoot); tlvdb_free(tlvRoot);
DropField(); DropFieldEx( channel );
return 6; return 6;
} }
@ -1706,7 +1713,7 @@ int CmdEMVRoca(const char *cmd) {
if (!pdol_data_tlv_data) { if (!pdol_data_tlv_data) {
PrintAndLogEx(ERR, "Can't create PDOL data."); PrintAndLogEx(ERR, "Can't create PDOL data.");
tlvdb_free(tlvRoot); tlvdb_free(tlvRoot);
DropField(); DropFieldEx( channel );
return 6; return 6;
} }
PrintAndLogEx(INFO, "PDOL data[%d]: %s", pdol_data_tlv_data_len, sprint_hex(pdol_data_tlv_data, pdol_data_tlv_data_len)); 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) { if (res) {
PrintAndLogEx(ERR, "GPO error(%d): %4x. Exit...", res, sw); PrintAndLogEx(ERR, "GPO error(%d): %4x. Exit...", res, sw);
tlvdb_free(tlvRoot); tlvdb_free(tlvRoot);
DropField(); DropFieldEx( channel );
return 7; return 7;
} }
ProcessGPOResponseFormat1(tlvRoot, buf, len, false); ProcessGPOResponseFormat1(tlvRoot, buf, len, false);
@ -1818,10 +1825,7 @@ out:
// free tlv object // free tlv object
tlvdb_free(tlvRoot); tlvdb_free(tlvRoot);
if ( channel == ECC_CONTACTLESS) DropFieldEx( channel );
DropField();
return 0; return 0;
} }

View file

@ -241,7 +241,7 @@ int EMVExchangeEx(EMVCommandChannel channel, bool ActivateField, bool LeaveField
int res = 0; int res = 0;
if (ActivateField) { if (ActivateField) {
DropField(); DropFieldEx( channel );
msleep(50); msleep(50);
} }
@ -262,8 +262,12 @@ int EMVExchangeEx(EMVCommandChannel channel, bool ActivateField, bool LeaveField
} }
break; break;
case ECC_CONTACT: case ECC_CONTACT:
#ifdef WITH_SMARTCARD
//int ExchangeAPDUSC(uint8_t *datain, int datainlen, bool activateCard, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen); //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); res = ExchangeAPDUSC(data, (IncludeLe?6:5) + apdu.Lc, ActivateField, LeaveFieldON, Result, (int)MaxResultLen, (int *)ResultLen);
#else
res = 1;
#endif
if (res) { if (res) {
return res; return res;
} }
@ -480,7 +484,7 @@ int EMVSearchPSE(EMVCommandChannel channel, bool ActivateField, bool LeaveFieldO
} }
if(!LeaveFieldON) if(!LeaveFieldON)
DropField(); DropFieldEx( channel );
return res; return res;
} }

View file

@ -58,6 +58,23 @@
"U9psmyPzK+Vsgw2jeRQ5JlKDyqE0hebfC1tvFu0CCrJFcw==\r\n" \ "U9psmyPzK+Vsgw2jeRQ5JlKDyqE0hebfC1tvFu0CCrJFcw==\r\n" \
"-----END CERTIFICATE-----\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 */ /* 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); const size_t additional_ca_pem_len = sizeof(additional_ca_pem);

View file

@ -250,9 +250,9 @@ int FIDOCheckDERAndGetKey(uint8_t *der, size_t derLen, bool verbose, uint8_t *pu
uint32_t verifyflags = 0; uint32_t verifyflags = 0;
res = mbedtls_x509_crt_verify(&cert, &cacert, NULL, NULL, &verifyflags, NULL, NULL); res = mbedtls_x509_crt_verify(&cert, &cacert, NULL, NULL, &verifyflags, NULL, NULL);
if (res) { 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 { } else {
PrintAndLog("Certificate OK."); PrintAndLog("Certificate OK.\n");
} }
if (verbose) { if (verbose) {

View file

@ -38,7 +38,7 @@ static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs,
flash_seg_t *seg; flash_seg_t *seg;
uint32_t last_end = 0; 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) { if (!ctx->segments) {
fprintf(stderr, "Out of memory\n"); fprintf(stderr, "Out of memory\n");
return -1; return -1;
@ -88,7 +88,7 @@ static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs,
uint8_t *data; uint8_t *data;
// make extra space if we need to move the data forward // 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) { if (!data) {
fprintf(stderr, "Error: Out of memory\n"); fprintf(stderr, "Error: Out of memory\n");
return -1; 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 new_length = this_end - prev_seg->start;
uint32_t this_offset = paddr - prev_seg->start; uint32_t this_offset = paddr - prev_seg->start;
uint32_t hole = this_offset - prev_seg->length; 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) { if (!new_data) {
fprintf(stderr, "Error: Out of memory\n"); fprintf(stderr, "Error: Out of memory\n");
free(data); 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); 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) { if (!phdrs) {
fprintf(stderr, "Out of memory\n"); fprintf(stderr, "Out of memory\n");
goto fail; goto fail;

View file

@ -59,7 +59,7 @@ static void usage(void)
static voidpf fpga_deflate_malloc(voidpf opaque, uInt items, uInt size) 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; z_stream compressed_fpga_stream;
if (hardnested_mode) { if (hardnested_mode) {
fpga_config = malloc(num_infiles * HARDNESTED_TABLE_SIZE); fpga_config = calloc(num_infiles * HARDNESTED_TABLE_SIZE, sizeof(uint8_t));
} else { } 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[] // read the input files. Interleave them into fpga_config[]
i = 0; i = 0;

View file

@ -40,7 +40,7 @@ static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs,
flash_seg_t *seg; flash_seg_t *seg;
uint32_t last_end = 0; 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) { if (!ctx->segments) {
fprintf(stderr, "Out of memory\n"); fprintf(stderr, "Out of memory\n");
return -1; return -1;
@ -90,7 +90,7 @@ static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs,
uint8_t *data; uint8_t *data;
// make extra space if we need to move the data forward // 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) { if (!data) {
fprintf(stderr, "Out of memory\n"); fprintf(stderr, "Out of memory\n");
return -1; 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); 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) { if (!phdrs) {
fprintf(stderr, "Out of memory\n"); fprintf(stderr, "Out of memory\n");
goto fail; goto fail;

View file

@ -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 cc_nr[13] = { 0 };
uint8_t div_key[8]; 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(cc_nr, cc_nr_p, 12);
memcpy(div_key, div_key_p, 8); 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 *address_data;
uint8_t div_key[8]; 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(address_data, address_data_p, address_data_size);
memcpy(div_key, div_key_p, 8); memcpy(div_key, div_key_p, 8);

View file

@ -52,7 +52,7 @@ typedef struct {
uint8_t * buffer; uint8_t * buffer;
uint8_t numbits; uint8_t numbits;
uint8_t position; uint8_t position;
}BitstreamOut; } BitstreamOut;
bool headBit( BitstreamIn *stream); bool headBit( BitstreamIn *stream);
bool tailBit( BitstreamIn *stream); bool tailBit( BitstreamIn *stream);

View file

@ -493,7 +493,7 @@ int bruteforceDump(uint8_t dump[], size_t dumpsize, uint16_t keytable[]) {
uint64_t t1 = msclock(); uint64_t t1 = msclock();
dumpdata* attack = (dumpdata* ) malloc(itemsize); dumpdata* attack = (dumpdata* ) calloc(itemsize, sizeof(uint8_t));
for (i = 0 ; i * itemsize < dumpsize ; i++ ) { for (i = 0 ; i * itemsize < dumpsize ; i++ ) {
memcpy(attack, dump + i * itemsize, itemsize); memcpy(attack, dump + i * itemsize, itemsize);

View file

@ -71,14 +71,14 @@ int saveFile(const char *preferredName, const char *suffix, const void* data, si
/*Opening file for writing in binary mode*/ /*Opening file for writing in binary mode*/
FILE *f = fopen(fileName, "wb"); FILE *f = fopen(fileName, "wb");
if (!f) { if (!f) {
PrintAndLogDevice(WARNING, "file not found or locked. '%s'", fileName); PrintAndLogDevice(WARNING, "file not found or locked. '" _YELLOW_(%s)"'", fileName);
free(fileName); free(fileName);
return 1; return 1;
} }
fwrite(data, 1, datalen, f); fwrite(data, 1, datalen, f);
fflush(f); fflush(f);
fclose(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); free(fileName);
return 0; 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*/ /*Opening file for writing in text mode*/
FILE *f = fopen(fileName, "w+"); FILE *f = fopen(fileName, "w+");
if (!f) { if (!f) {
PrintAndLogDevice(WARNING, "file not found or locked. '%s'", fileName); PrintAndLogDevice(WARNING, "file not found or locked. '" _YELLOW_(%s)"'", fileName);
retval = 1; retval = 1;
goto out; goto out;
} }
@ -130,7 +130,7 @@ int saveFileEML(const char *preferredName, const char *suffix, uint8_t* data, si
} }
fflush(f); fflush(f);
fclose(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: out:
free(fileName); 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)); int res = json_dump_file(root, fileName, JSON_INDENT(2));
if (res) { 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); json_decref(root);
retval = 200; retval = 200;
goto out; goto out;
} }
PrintAndLogDevice(SUCCESS, "File `%s` saved.", fileName); PrintAndLogDevice(SUCCESS, "saved to json file " _YELLOW_(%s), fileName);
json_decref(root); json_decref(root);
out: out:
@ -266,7 +265,7 @@ int loadFile(const char *preferredName, const char *suffix, void* data, size_t*
FILE *f = fopen(fileName, "rb"); FILE *f = fopen(fileName, "rb");
if ( !f ) { if ( !f ) {
PrintAndLogDevice(FAILED, "file: %s: not found or locked.", fileName); PrintAndLogDevice(WARNING, "file not found or locked. '" _YELLOW_(%s)"'", fileName);
retval = 1; retval = 1;
goto out; goto out;
} }
@ -305,7 +304,7 @@ int loadFile(const char *preferredName, const char *suffix, void* data, size_t*
memcpy( (data), dump, bytes_read); memcpy( (data), dump, bytes_read);
free(dump); 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; *datalen = bytes_read;
@ -328,7 +327,7 @@ int loadFileEML(const char *preferredName, const char *suffix, void* data, size_
FILE *f = fopen(fileName, "r"); FILE *f = fopen(fileName, "r");
if ( !f ) { if ( !f ) {
PrintAndLogDevice(FAILED, "file: %s: not found or locked.", fileName); PrintAndLogDevice(WARNING, "file not found or locked. '" _YELLOW_(%s)"'", fileName);
retval = 1; retval = 1;
goto out; goto out;
} }
@ -359,7 +358,7 @@ int loadFileEML(const char *preferredName, const char *suffix, void* data, size_
} }
} }
fclose(f); 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; *datalen = counter;
out: out:
@ -382,13 +381,13 @@ int loadFileJSON(const char *preferredName, const char *suffix, void* data, size
root = json_load_file(fileName, 0, &error); root = json_load_file(fileName, 0, &error);
if (!root) { 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; retval = 2;
goto out; goto out;
} }
if (!json_is_object(root)) { 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; retval = 3;
goto out; 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: out:
json_decref(root); json_decref(root);
free(fileName); free(fileName);
@ -479,7 +478,7 @@ int loadFileDICTIONARY(const char *preferredName, const char *suffix, void* data
FILE *f = fopen(fileName, "r"); FILE *f = fopen(fileName, "r");
if ( !f ) { if ( !f ) {
PrintAndLogDevice(FAILED, "file: %s: not found or locked.", fileName); PrintAndLogDevice(WARNING, "file not found or locked. '" _YELLOW_(%s)"'", fileName);
retval = 1; retval = 1;
goto out; goto out;
} }
@ -512,7 +511,7 @@ int loadFileDICTIONARY(const char *preferredName, const char *suffix, void* data
counter += (keylen >> 1); counter += (keylen >> 1);
} }
fclose(f); 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; *datalen = counter;
out: out:
free(fileName); free(fileName);

View file

@ -1,72 +1,115 @@
local manufacturer = {} local m = {}
manufacturer[0x01]='Motorola [UK]' m[0x01]='Motorola UK'
manufacturer[0x02]='STMicroelectronics SA [France]' m[0x02]='ST Microelectronics SA France'
manufacturer[0x03]='Hitachi, Ltd [Japan]' m[0x03]='Hitachi, Ltd Japan'
manufacturer[0x04]='NXP Semiconductors [Germany]' m[0x04]='NXP Semiconductors Germany'
manufacturer[0x05]='Infineon Technologies AG [Germany]' m[0x05]='Infineon Technologies AG Germany'
manufacturer[0x06]='Cylink [USA]' m[0x06]='Cylink USA'
manufacturer[0x07]='Texas Instrument [France]' m[0x07]='Texas Instrument France'
manufacturer[0x08]='Fujitsu Limited [Japan]' m[0x08]='Fujitsu Limited Japan'
manufacturer[0x09]='Matsushita Electronics Corporation, Semiconductor Company [Japan]' m[0x09]='Matsushita Electronics Corporation, Semiconductor Company Japan'
manufacturer[0x0A]='NEC [Japan]' m[0x0A]='NEC Japan'
manufacturer[0x0B]='Oki Electric Industry Co. Ltd [Japan]' m[0x0B]='Oki Electric Industry Co. Ltd Japan'
manufacturer[0x0C]='Toshiba Corp. [Japan]' m[0x0C]='Toshiba Corp. Japan'
manufacturer[0x0D]='Mitsubishi Electric Corp. [Japan]' m[0x0D]='Mitsubishi Electric Corp. Japan'
manufacturer[0x0E]='Samsung Electronics Co. Ltd [Korea]' m[0x0E]='Samsung Electronics Co. Ltd Korea'
manufacturer[0x0F]='Hynix [Korea]' m[0x0F]='Hynix / Hyundai, Korea'
manufacturer[0x10]='LG-Semiconductors Co. Ltd [Korea]' m[0x10]='LG-Semiconductors Co. Ltd Korea'
manufacturer[0x11]='Emosyn-EM Microelectronics [USA]' m[0x11]='Emosyn-EM Microelectronics USA'
manufacturer[0x12]='INSIDE Technology [France]' m[0x12]='INSIDE Technology France'
manufacturer[0x13]='ORGA Kartensysteme GmbH [Germany]' m[0x13]='ORGA Kartensysteme GmbH Germany'
manufacturer[0x14]='SHARP Corporation [Japan]' m[0x14]='SHARP Corporation Japan'
manufacturer[0x15]='ATMEL [France]' m[0x15]='ATMEL France'
manufacturer[0x16]='EM Microelectronic-Marin SA [Switzerland]' m[0x16]='EM Microelectronic-Marin SA Switzerland'
manufacturer[0x17]='KSW Microtec GmbH [Germany]' m[0x17]='KSW Microtec GmbH Germany'
manufacturer[0x18]='ZMD AG [Germany]' m[0x18]='ZMD AG Germany'
manufacturer[0x19]='XICOR, Inc. [USA]' m[0x19]='XICOR, Inc. USA'
manufacturer[0x1A]='Sony Corporation [Japan]' m[0x1A]='Sony Corporation Japan'
manufacturer[0x1B]='Malaysia Microelectronic Solutions Sdn. Bhd [Malaysia]' m[0x1B]='Malaysia Microelectronic Solutions Sdn. Bhd Malaysia'
manufacturer[0x1C]='Emosyn [USA]' m[0x1C]='Emosyn USA'
manufacturer[0x1D]='Shanghai Fudan Microelectronics Co. Ltd. P.R. [China]' m[0x1D]='Shanghai Fudan Microelectronics Co. Ltd. P.R. China'
manufacturer[0x1E]='Magellan Technology Pty Limited [Australia]' m[0x1E]='Magellan Technology Pty Limited Australia'
manufacturer[0x1F]='Melexis NV BO [Switzerland]' m[0x1F]='Melexis NV BO Switzerland'
manufacturer[0x20]='Renesas Technology Corp. [Japan]' m[0x20]='Renesas Technology Corp. Japan'
manufacturer[0x21]='TAGSYS [France]' m[0x21]='TAGSYS France'
manufacturer[0x22]='Transcore [USA]' m[0x22]='Transcore USA'
manufacturer[0x23]='Shanghai belling corp., ltd. [China]' m[0x23]='Shanghai belling corp., ltd. China'
manufacturer[0x24]='Masktech Germany Gmbh [Germany]' m[0x24]='Masktech Germany Gmbh Germany'
manufacturer[0x25]='Innovision Research and Technology Plc [UK]' m[0x25]='Innovision Research and Technology Plc UK'
manufacturer[0x26]='Hitachi ULSI Systems Co., Ltd. [Japan]' m[0x26]='Hitachi ULSI Systems Co., Ltd. Japan'
manufacturer[0x27]='Cypak AB [Sweden]' m[0x27]='Cypak AB Sweden'
manufacturer[0x28]='Ricoh [Japan]' m[0x28]='Ricoh Japan'
manufacturer[0x29]='ASK [France]' m[0x29]='ASK France'
manufacturer[0x2A]='Unicore Microsystems, LLC [RussianFederation]' m[0x2A]='Unicore Microsystems, LLC RussianFederation'
manufacturer[0x2B]='Dallas Semiconductor/Maxim [USA]' m[0x2B]='Dallas Semiconductor/Maxim USA'
manufacturer[0x2C]='Impinj, Inc. [USA]' m[0x2C]='Impinj, Inc. USA'
manufacturer[0x2D]='RightPlug Alliance [USA]' m[0x2D]='RightPlug Alliance USA'
manufacturer[0x2E]='Broadcom Corporation [USA]' m[0x2E]='Broadcom Corporation USA'
manufacturer[0x2F]='MStar Semiconductor, Inc Taiwan, [ROC]' m[0x2F]='MStar Semiconductor, Inc Taiwan, ROC'
manufacturer[0x30]='BeeDar Technology Inc. [USA]' m[0x30]='BeeDar Technology Inc. USA'
manufacturer[0x31]='RFIDsec [Denmark]' m[0x31]='RFIDsec Denmark'
manufacturer[0x32]='Schweizer Electronic AG [Germany]' m[0x32]='Schweizer Electronic AG Germany'
manufacturer[0x33]='AMIC Technology Corp [Taiwan]' m[0x33]='AMIC Technology Corp Taiwan'
manufacturer[0x34]='Mikron JSC [Russia]' m[0x34]='Mikron JSC Russia'
manufacturer[0x35]='Fraunhofer Institute for Photonic Microsystems [Germany]' m[0x35]='Fraunhofer Institute for Photonic Microsystems Germany'
manufacturer[0x36]='IDS Microchip AG [Switzerland]' m[0x36]='IDS Microchip AG Switzerland'
manufacturer[0x37]='Kovio [USA]' m[0x37]='Kovio USA'
manufacturer[0x38]='HMT Microelectronic Ltd [Switzerland]' m[0x38]='HMT Microelectronic Ltd Switzerland'
manufacturer[0x39]='Silicon Craft Technology [Thailand]' m[0x39]='Silicon Craft Technology Thailand'
manufacturer[0x3A]='Advanced Film Device Inc. [Japan]' m[0x3A]='Advanced Film Device Inc. Japan'
manufacturer[0x3B]='Nitecrest Ltd [UK]' m[0x3B]='Nitecrest Ltd UK'
manufacturer[0x3C]='Verayo Inc. [USA]' m[0x3C]='Verayo Inc. USA'
manufacturer[0x3D]='HID Global [USA]' m[0x3D]='HID Global USA'
manufacturer[0x3E]='Productivity Engineering Gmbh [Germany]' m[0x3E]='Productivity Engineering Gmbh Germany'
manufacturer[0x3F]='Austriamicrosystems AG (reserved) [Austria]' m[0x3F]='Austriamicrosystems AG (reserved) Austria'
manufacturer[0x40]='Gemalto SA [France]' m[0x40]='Gemalto SA France'
manufacturer[0x41]='Renesas Electronics Corporation [Japan]' m[0x41]='Renesas Electronics Corporation Japan'
manufacturer[0x42]='3Alogics Inc [Korea]' m[0x42]='3Alogics Inc Korea'
manufacturer[0x43]='Top TroniQ Asia Limited Hong [Kong]' m[0x43]='Top TroniQ Asia Limited Hong Kong'
manufacturer[0x44]='Gentag Inc (USA) [USA]' 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 { return {
lookupManufacturer = function (value) lookupManufacturer = function (value)
@ -76,8 +119,6 @@ return {
value = v value = v
end end
return manufacturer[value] or "no tag-info available" return m[value] or "no tag-info available"
end, end,
} }

View file

@ -173,18 +173,19 @@ int mfCheckKeys_fast( uint8_t sectorsCnt, uint8_t firstChunk, uint8_t lastChunk,
// success array. each byte is status of key // success array. each byte is status of key
uint8_t arr[80]; uint8_t arr[80];
uint64_t foo = bytes_to_num(resp.d.asBytes+480, 8); uint64_t foo = 0;
for (uint8_t i = 0; i < 64; ++i) { uint16_t bar = 0;
arr[i] = (foo >> i) & 0x1; foo = bytes_to_num(resp.d.asBytes+480, 8);
} bar = (resp.d.asBytes[489] << 8 | resp.d.asBytes[488]);
foo = bytes_to_num(resp.d.asBytes+488, 2);
for (uint8_t i = 0; i < 16; ++i) {
arr[i+64] = (foo >> i) & 0x1;
}
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 // initialize storage for found keys
icesector_t *tmp = NULL; icesector_t *tmp = calloc(sectorsCnt, sizeof(icesector_t));
tmp = calloc(sectorsCnt, sizeof(icesector_t));
if (tmp == NULL) if (tmp == NULL)
return 1; return 1;
memcpy(tmp, resp.d.asBytes, sectorsCnt * sizeof(icesector_t) ); memcpy(tmp, resp.d.asBytes, sectorsCnt * sizeof(icesector_t) );

View file

@ -215,11 +215,11 @@ const char *get_my_executable_directory(void) {
static void set_my_executable_path(void) { static void set_my_executable_path(void) {
int path_length = wai_getExecutablePath(NULL, 0, NULL); int path_length = wai_getExecutablePath(NULL, 0, NULL);
if (path_length != -1) { 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; int dirname_length = 0;
if (wai_getExecutablePath(my_executable_path, path_length, &dirname_length) != -1) { if (wai_getExecutablePath(my_executable_path, path_length, &dirname_length) != -1) {
my_executable_path[path_length] = '\0'; 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); strncpy(my_executable_directory, my_executable_path, dirname_length+1);
my_executable_directory[dirname_length+1] = '\0'; my_executable_directory[dirname_length+1] = '\0';
} }
@ -321,9 +321,9 @@ int main(int argc, char* argv[]) {
} else { } else {
if (addLuaExec){ if (addLuaExec){
// add "script run " to command // add "script run " to command
char *ctmp = NULL;
int len = strlen(script_cmd) + 11 + 1; 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); memset(ctmp, 0, len);
strcpy(ctmp, "script run "); strcpy(ctmp, "script run ");
strcpy(&ctmp[11], script_cmd); strcpy(&ctmp[11], script_cmd);

View file

@ -377,7 +377,9 @@ ipqx:
/* allocate argument array */ /* allocate argument array */
args = argc - optind; 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"); uerror("cannot allocate memory for argument list");
return 0; return 0;
} }

View file

@ -118,7 +118,7 @@ char * mtostr(const model_t *model) {
+ (checkstr && *checkstr ? strlen(checkstr) : 6) + (checkstr && *checkstr ? strlen(checkstr) : 6)
+ (magicstr && *magicstr ? strlen(magicstr) : 6) + (magicstr && *magicstr ? strlen(magicstr) : 6)
+ (model->name && *model->name ? 2 + strlen(model->name) : 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(strbuf, "\"%s\"", model->name);
sprintf(string, sprintf(string,
"width=%lu " "width=%lu "

View file

@ -349,7 +349,7 @@ pxsubs(const poly_t poly, int flags, int bperhx, unsigned long start, unsigned l
size *= cperhx; size *= cperhx;
if(!size || ~flags & P_SPACE) ++size; /* for trailing null */ 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"); uerror("cannot allocate memory for string");
size = end - start; size = end - start;

View file

@ -811,7 +811,9 @@ int mbynam(model_t *dest, const char *key) {
if (!aliases->name) if (!aliases->name)
return(-1); 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"); uerror("[!] cannot allocate memory for comparison string");
return(0); return(0);
} }
@ -861,7 +863,9 @@ char * mnames(void) {
++aptr; ++aptr;
} }
if (!size) return(NULL); if (!size) return(NULL);
if ((string = malloc(size))) {
string = calloc(size, sizeof(char));
if (string) {
aptr = aliases; aptr = aliases;
sptr = string; sptr = string;
while (aptr->name) { while (aptr->name) {

View file

@ -173,8 +173,9 @@ modpol(const poly_t init, int rflags, int args, const poly_t *argpolys) {
unsigned long alen, blen; unsigned long alen, blen;
if(args < 2) return(NULL); 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"); uerror("cannot allocate memory for codeword table");
rptr = result; rptr = result;
@ -240,7 +241,8 @@ engini(int *resc, model_t **result, const poly_t divisor, int flags, int args, c
dlen = plen(divisor); dlen = plen(divisor);
/* Allocate the CRC matrix */ /* 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"); uerror("cannot allocate memory for CRC matrix");
/* Find arguments of the two shortest lengths */ /* Find arguments of the two shortest lengths */

View file

@ -51,7 +51,8 @@ int scandir (const char *dir,
nl = ntmp; nl = ntmp;
} }
if (!(etmp = (struct dirent *) malloc (sizeof *ent))) { etmp = (struct dirent *) calloc (sizeof *ent, sizeof(char));
if (!etmp) {
err_no = 1; err_no = 1;
break; break;
} }

View file

@ -758,6 +758,15 @@ int set_pm3_libraries(lua_State *L) {
//-- remove the global environment table from the stack //-- remove the global environment table from the stack
lua_pop(L, 1); 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) //-- Last but not least, add to the LUA_PATH (package.path in lua)
// so we can load libraries from the ./lualib/ - directory // 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]; 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_DIRECTORY);
strcat(libraries_path, LUA_LIBRARIES_WILDCARD); strcat(libraries_path, LUA_LIBRARIES_WILDCARD);
setLuaPath(L, libraries_path); setLuaPath(L, libraries_path);
return 1; return 1;
} }

View file

@ -5,7 +5,7 @@ local utils = require('utils')
copyright = 'Copyright (c) 2018 IceSQL AB. All rights reserved.' copyright = 'Copyright (c) 2018 IceSQL AB. All rights reserved.'
author = 'Christian Herrmann' author = 'Christian Herrmann'
version = 'v1.0.3' version = 'v1.0.4'
desc = [[ desc = [[
This script tries to set UID on a IS15693 SLIX magic card This script tries to set UID on a IS15693 SLIX magic card
Remember the UID ->MUST<- start with 0xE0 Remember the UID ->MUST<- start with 0xE0
@ -15,6 +15,8 @@ example = [[
-- ISO15693 slix magic tag -- ISO15693 slix magic tag
script run iso15_magic -u E004013344556677 script run iso15_magic -u E004013344556677
script run iso15_magic -u E004013344556677 -a
]] ]]
usage = [[ usage = [[
script run iso15_magic -h -u <uid> script run iso15_magic -h -u <uid>
@ -22,6 +24,7 @@ script run iso15_magic -h -u <uid>
Arguments: Arguments:
-h : this help -h : this help
-u <UID> : UID (16 hexsymbols) -u <UID> : UID (16 hexsymbols)
-a : use offical pm3 repo ISO15 commands instead of iceman fork.
]] ]]
local DEBUG = true local DEBUG = true
@ -82,11 +85,13 @@ function main(args)
print() print()
local uid = 'E004013344556677' local uid = 'E004013344556677'
local use_iceman = true
-- Read the parameters -- 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 == "h" then return help() end
if o == "u" then uid = a end if o == "u" then uid = a end
if o == "a" then use_iceman = false end
end end
-- uid string checks -- uid string checks
@ -103,8 +108,11 @@ function main(args)
core.clearCommandBuffer() core.clearCommandBuffer()
magicUID_iceman(block0, block1) if use_iceman then
--magicUID_offical(block0, block1) magicUID_iceman(block0, block1)
else
magicUID_offical(block0, block1)
end
end end
main(args) main(args)

View file

@ -513,8 +513,8 @@ function readFromPM3()
return tag return tag
end end
function padString(str) local function padString(str)
if (str:len() == 1) then if (#str == 1) then
return '0'..str return '0'..str
end end
@ -524,73 +524,84 @@ end
--- ---
-- write virtual Tag to real Tag -- write virtual Tag to real Tag
function writeToTag(tag) function writeToTag(tag)
local bytes local bytes
local filename='MylegicClone.hex' local filename = 'MylegicClone.hex'
local taglen=22 local taglen = 22
if(utils.confirm(acred.."\nplace the (empty) Tag onto the PM3\nand confirm writing to this Tag: "..acoff) == false) then if(utils.confirm(acred.."\nplace the (empty) Tag onto the PM3\nand confirm writing to this Tag: "..acoff) == false) then
return return
end end
-- get used bytes / tag-len
if(istable(tag.SEG)) then -- get used bytes / tag-len
if (istable(tag.Bck)) then if (istable(tag.SEG)) then
for i=0, #tag.SEG do if (istable(tag.Bck)) then
taglen=taglen+tag.SEG[i].len+5 for i=0, #tag.SEG do
end taglen = taglen + tag.SEG[i] . len + 5
end end
local uid_old=tag.MCD..tag.MSN0..tag.MSN1..tag.MSN2 end
-- read new tag into memory so we can xor the new data with the new MCC local uid_old = tag.MCD..tag.MSN0..tag.MSN1..tag.MSN2
outTAG=readFromPM3()
outbytes=tagToBytes(outTAG) -- read new tag into memory so we can xor the new data with the new MCC
-- copy 'inputbuffer' to 'outputbuffer' outTAG = readFromPM3()
tag.MCD = outbytes[1] outbytes = tagToBytes(outTAG)
tag.MSN0 = outbytes[2] -- copy 'inputbuffer' to 'outputbuffer'
tag.MSN1 = outbytes[3] tag.MCD = outbytes[1]
tag.MSN2 = outbytes[4] tag.MSN0 = outbytes[2]
tag.MCC = outbytes[5] tag.MSN1 = outbytes[3]
-- recheck all segments-crc/kghcrc (only on a credential) tag.MSN2 = outbytes[4]
if(istable(tag.Bck)) then tag.MCC = outbytes[5]
checkAllSegCrc(tag) -- recheck all segments-crc/kghcrc (only on a credential)
checkAllKghCrc(tag) if (istable(tag.Bck)) then
local uid_new=tag.MCD..tag.MSN0..tag.MSN1..tag.MSN2 checkAllSegCrc(tag)
for i=0, #tag.SEG do checkAllKghCrc(tag)
if (check43rdPartyCash1(uid_old, tag.SEG[i].data)) then local uid_new = tag.MCD..tag.MSN0..tag.MSN1..tag.MSN2
io.write(accyan.."\nfixing known checksums"..acoff.." ... ") for i=0, #tag.SEG do
if (fix3rdPartyCash1(uid_new, tag.SEG[i].data)) then if (check43rdPartyCash1(uid_old, tag.SEG[i].data)) then
io.write(acgreen.." done\n"..acoff) io.write(accyan.."\nfixing known checksums"..acoff.." ... ")
else oops("\nsomething went wrong at the repair of the 3rd-party-cash-segment") end if (fix3rdPartyCash1(uid_new, tag.SEG[i].data)) then
end io.write(acgreen.." done\n"..acoff)
end else
end oops("\nsomething went wrong at the repair of the 3rd-party-cash-segment")
bytes=tagToBytes(tag) end
-- master-token-crc end
if (tag.Type ~= "SAM") then bytes[22] = calcMtCrc(bytes) end end
if (bytes) then end
print("write temp-file '"..filename.."'") bytes = tagToBytes(tag)
print(accyan) -- master-token-crc
writeFile(bytes, filename..".bin") if (tag.Type ~= "SAM") then
print(acoff) bytes[22] = calcMtCrc(bytes)
end end
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 if (taglen > 0) then
WriteBytes = utils.input(acyellow.."enter number of bytes to write?"..acoff, taglen) WriteBytes = utils.input(acyellow.."enter number of bytes to write?"..acoff, taglen)
-- load file into pm3-buffer -- 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 cmd = 'hf legic eload 2 '..filename
core.console(cmd) core.console(cmd)
-- write pm3-buffer to Tag -- write pm3-buffer to Tag
for i=0, WriteBytes do for i=0, WriteBytes do
if (i > 6) then if (i > 6) then
cmd = 'hf legic write o '..string.format("%x", i)..' d '..padString(bytes[i]) cmd = ("hf legic write o %x d %s "):format(i, padString(bytes[i]))
print(acgreen..cmd..acoff) print(acgreen..cmd..acoff)
core.console(cmd) core.console(cmd)
core.clearCommandBuffer()
elseif (i == 6) then elseif (i == 6) then
-- write DCF in reverse order (requires 'mosci-patch') -- write DCF in reverse order (requires 'mosci-patch')
cmd = 'hf legic write o 05 d '..padString(bytes[i-1])..padString(bytes[i]) cmd = ('hf legic write o 05 d %s%s'):format(padString(bytes[i-1]), padString(bytes[i]))
print(acgreen..cmd..acoff) print(acgreen..cmd..acoff)
core.console(cmd) core.console(cmd)
elseif (i == 5) then core.clearCommandBuffer()
elseif (i == 5) then
print(acgreen.."skip byte 0x05 - will be written next step"..acoff) print(acgreen.."skip byte 0x05 - will be written next step"..acoff)
else else
print(acgreen.."skip byte 0x00-0x04 - unwritable area"..acoff) print(acgreen.."skip byte 0x00-0x04 - unwritable area"..acoff)
@ -603,26 +614,28 @@ end
--- File I/O --- --- File I/O ---
--- ---
-- read file into virtual-tag -- read file into virtual-tag
function readFile(filename) local function readFile(filename)
print(accyan) print(accyan)
local bytes = {} local bytes = {}
local tag = {} local tag = {}
if file_check(filename) == false then return oops("input file: "..filename.." not found") end 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 -- make plain bytes
bytes = xorBytes(bytes,bytes[5]) bytes = xorBytes(bytes,bytes[5])
print("create virtual tag from ".. #bytes .. " bytes") print("create virtual tag from ".. #bytes .. " bytes")
-- create Tag for plain bytes -- create Tag for plain bytes
tag=createTagTable() tag = createTagTable()
-- load plain bytes to tag-table -- load plain bytes to tag-table
print(acoff) print(acoff)
tag=bytesToTag(bytes, tag) tag = bytesToTag(bytes, tag)
return tag return tag
end end
--- ---
@ -631,14 +644,16 @@ function writeFile(bytes, filename)
if (filename ~= 'MylegicClone.hex') then if (filename ~= 'MylegicClone.hex') then
if (file_check(filename)) then if (file_check(filename)) then
local answer = confirm("\nthe output-file "..filename.." already exists!\nthis will delete the previous content!\ncontinue?") 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
end end
local line local line
local bcnt=0 local bcnt = 0
local fho,err = io.open(filename, "w") local fho, err = io.open(filename, "w")
if err then oops("OOps ... failed to open output-file ".. filename) end if err then
bytes=xorBytes(bytes, bytes[5]) return oops("OOps ... failed to open output-file ".. filename)
end
bytes = xorBytes(bytes, bytes[5])
for i = 1, #bytes do for i = 1, #bytes do
if (bcnt == 0) then if (bcnt == 0) then
line = bytes[i] line = bytes[i]
@ -662,96 +677,96 @@ end
--- Map related --- --- Map related ---
--- ---
-- make tagMap -- make tagMap
function makeTagMap() local function makeTagMap()
local tagMap={} local tagMap = {}
if (#tagMap == 0) then if (#tagMap == 0) then
tagMap['name'] = input(accyan.."enter Name for this Map: "..acoff , "newTagMap") tagMap['name'] = input(accyan.."enter Name for this Map: "..acoff , "newTagMap")
tagMap['mappings']={} tagMap['mappings'] = {}
tagMap['crc8']={} tagMap['crc8'] = {}
-- insert fixed Tag-CRC -- insert fixed Tag-CRC
table.insert(tagMap.crc8, {name='TAG-CRC', pos=5, seq={1, 4}}) table.insert(tagMap.crc8, {name = 'TAG-CRC', pos = 5, seq = {1, 4}})
tagMap['crc16']={} tagMap['crc16'] = {}
end end
print(accyan.."new tagMap created"..acoff) print(accyan.."new tagMap created"..acoff)
return tagMap return tagMap
end end
--- ---
-- save mapping to file -- save mapping to file
function saveTagMap(map, filename) local function saveTagMap(map, filename)
if (string.len(filename)>0) then if (string.len(filename)>0) then
if (file_check(filename)) then if (file_check(filename)) then
local answer = confirm("\nthe output-file "..filename.." alredy exists!\nthis will delete the previous content!\ncontinue?") 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 if not answer then return print("user abort") end
end end
end end
local line local line
local fho,err = io.open(filename, "w") local fho,err = io.open(filename, "w")
if err then oops("OOps ... faild to open output-file ".. filename) end if err then oops("OOps ... faild to open output-file ".. filename) end
-- write line to new file -- write line to new file
for k, v in pairs(map) do for k, v in pairs(map) do
if (istable(v)) then if (istable(v)) then
for k2, v2 in pairs(v) do for k2, v2 in pairs(v) do
if (k=='mappings') then if (k == 'mappings') then
fho:write(k..","..k2..","..v2['name']..","..v2['start']..","..v2['end']..","..((v2['highlight']) and "1" or "0").."\n") fho:write(k..","..k2..","..v2['name']..","..v2['start']..","..v2['end']..","..((v2['highlight']) and "1" or "0").."\n")
elseif (k=="crc8") then elseif (k == "crc8") then
local tmp="" local tmp = ""
tmp=k..","..k2..","..v2['name']..","..v2['pos'].."," tmp = k..","..k2..","..v2['name']..","..v2['pos']..","
tmp=tmp..tbl2seqstr(v2['seq']) tmp=tmp..tbl2seqstr(v2['seq'])
fho:write(tmp.."\n") fho:write(tmp.."\n")
end end
end end
else else
fho:write(k..","..v.."\n") fho:write(k..","..v.."\n")
end end
end end
fho:close() fho:close()
return true return true
end end
--- ---
-- toggle higligh -- toggle higligh
function toggleHighlight(tbl) local function toggleHighlight(tbl)
if (tbl['highlight']) then if (tbl['highlight']) then
tbl['highlight'] = false tbl['highlight'] = false
else else
tbl['highlight'] = true tbl['highlight'] = true
end end
return tbl return tbl
end end
--- ---
-- return table od seqence-string -- return table od seqence-string
function seqstr2tbl(seqstr) local function seqstr2tbl(seqstr)
local s=split(seqstr) local s = split(seqstr)
local res={} local res = {}
if (#s>=1) then if (#s >= 1) then
for sk, sv in pairs(s) do for sk, sv in pairs(s) do
s2=split(sv, '-') s2 = split(sv, '-')
if(#s2==2) then if(#s2 == 2) then
table.insert(res, s2[1]) table.insert(res, s2[1])
table.insert(res, s2[2]) table.insert(res, s2[2])
end end
end end
end end
return res return res
end end
--- ---
-- return sequence-string from table -- return sequence-string from table
function tbl2seqstr(seqtbl) local function tbl2seqstr(seqtbl)
local res="" local res = ""
if (istable(seqtbl)) then if (istable(seqtbl)) then
for sk, sv in pairs(seqtbl) do for sk, sv in pairs(seqtbl) do
res=res..sv..((sk%2==0) and "," or "-") res = res..sv..((sk%2==0) and "," or "-")
end end
if (string.sub(res, string.len(res))==",") then if (string.sub(res, string.len(res))== ",") then
res=string.sub(res, 1, string.len(res)-1) res = string.sub(res, 1, string.len(res)-1)
end end
end end
return res return res
end end
--- ---

View file

@ -12,8 +12,10 @@ This is a script which automates cracking and dumping mifare classic cards. It s
place by the device. place by the device.
Arguments: 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: Output files from this operation:
<uid>.eml - emulator file <uid>.eml - emulator file
@ -73,12 +75,12 @@ local function nested(key,sak)
if 0x18 == sak then --NXP MIFARE Classic 4k | Plus 4k | Ev1 4k if 0x18 == sak then --NXP MIFARE Classic 4k | Plus 4k | Ev1 4k
typ = 4 typ = 4
elseif 0x08 == sak then -- NXP MIFARE CLASSIC 1k | Plus 2k | Ev1 1K 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 elseif 0x09 == sak then -- NXP MIFARE Mini 0.3k
typ = 0 typ = 0
elseif 0x10 == sak then-- "NXP MIFARE Plus 2k" elseif 0x10 == sak then-- "NXP MIFARE Plus 2k"
typ = 2 typ = 2
elseif 0x01 == sak then-- "NXP MIFARE TNP3xxx 1K" elseif 0x01 == sak then-- "NXP MIFARE TNP3xxx 1K"
typ = 1 typ = 1
else else
print("I don't know how many sectors there are on this type of card, defaulting to 16") 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) core.console(cmd)
end end
local function dump(uid) local function dump(uid, numsectors)
dbg('dumping tag memory') 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 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 -- Save the global args, those are *our* arguments
local myargs = args local myargs = args
-- Set the arguments for htmldump script -- Set the arguments for htmldump script
args =("-o %s.html"):format(uid) args =('-i %s -o %s.html'):format(dumpfile, uid)
-- call it -- call it
require('../scripts/htmldump') require('htmldump')
args =""
-- dump to emulator -- 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... -- Set back args. Not that it's used, just for the karma...
args = myargs args = myargs
end end
@ -177,9 +197,9 @@ local function main(args)
print("Found valid key: "..key); print("Found valid key: "..key);
end end
-- Use nested attack -- Use nested attack
nested(key,sak) nested(key, sak)
-- Dump info -- Dump info
dump(uid) dump(uid, sak)
if #key == 12 then exit = true end if #key == 12 then exit = true end
else else

View file

@ -24,13 +24,13 @@ local example = "script run xxx"
local author = "Martin Holst Swende & Asper" local author = "Martin Holst Swende & Asper"
--- ---
-- PrintAndLog -- PrintAndLog
function prlog(...) local function prlog(...)
-- TODO; replace this with a call to the proper PrintAndLog -- TODO; replace this with a call to the proper PrintAndLog
print(...) print(...)
end end
--- ---
-- This is only meant to be used when errors occur -- This is only meant to be used when errors occur
function oops(err) local function oops(err)
prlog("ERROR: ",err) prlog("ERROR: ",err)
return nil,err return nil,err
end end
@ -70,13 +70,13 @@ local utils = {
--- ---
-- Usage help -- Usage help
function help() local function help()
prlog(desc) prlog(desc)
prlog("Example usage") prlog("Example usage")
prlog(example) prlog(example)
end end
function debug(...) local function debug(...)
if DEBUG then if DEBUG then
prlog("debug:", ...) prlog("debug:", ...)
end end
@ -158,7 +158,7 @@ end
--- This function is a lua-implementation of --- This function is a lua-implementation of
-- cmdhf14a.c:waitCmd(uint8_t iSelect) -- cmdhf14a.c:waitCmd(uint8_t iSelect)
function waitCmd(iSelect) local function waitCmd(iSelect)
local response = core.WaitForResponseTimeout(cmds.CMD_ACK,1000) local response = core.WaitForResponseTimeout(cmds.CMD_ACK,1000)
if response then if response then
local count,cmd,arg0,arg1,arg2 = bin.unpack('LLLL',response) local count,cmd,arg0,arg1,arg2 = bin.unpack('LLLL',response)

View file

@ -21,6 +21,9 @@ Arguments:
-o <offset> : memory offset, default is 0 -o <offset> : memory offset, default is 0
-l <length> : length in bytes, default is 256 -l <length> : length in bytes, default is 256
-k <keylen> : key length in bytes <4|6|8> , default is 4 -k <keylen> : 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 = example =
[[ [[
@ -67,7 +70,7 @@ local function main(args)
local keylength = 4 local keylength = 4
local usedkey = false 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 -- help
if o == "h" then return help() end if o == "h" then return help() end
@ -80,6 +83,10 @@ local function main(args)
-- keylength -- keylength
if o == "k" then keylength = tonumber(a); usedkey = true end 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 end
if length < 0 or length > 256 then if length < 0 or length > 256 then

View file

@ -72,6 +72,7 @@ local function sendCmds( cmds )
if cmds[i] then if cmds[i] then
print ( cmds[i] ) print ( cmds[i] )
core.console( cmds[i] ) core.console( cmds[i] )
core.clearCommandBuffer()
end end
end end
end end

View file

@ -37,13 +37,12 @@ Arguments:
0020 - Swapforce 0020 - Swapforce
]] ]]
-- This is only meant to be used when errors occur -- This is only meant to be used when errors occur
function oops(err) local function oops(err)
print("ERROR: ",err) print("ERROR: ",err)
end end
-- Usage help -- Usage help
function help() local function help()
print(desc) print(desc)
print("Example usage") print("Example usage")
print(example) print(example)
@ -64,7 +63,7 @@ local function waitCmd()
end end
local function readblock( blocknum, keyA ) 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} cmd = Command:new{cmd = cmds.CMD_MIFARE_READBL, arg1 = blocknum, arg2 = 0, arg3 = 0, data = keyA}
err = core.SendCommand(cmd:getBytes()) err = core.SendCommand(cmd:getBytes())
if err then return nil, err end if err then return nil, err end
@ -72,8 +71,9 @@ local function readblock( blocknum, keyA )
if err then return nil, err end if err then return nil, err end
return block0 return block0
end end
local function readmagicblock( blocknum ) local function readmagicblock( blocknum )
-- Read block 0 -- Read block N
local CSETBLOCK_SINGLE_OPERATION = 0x1F local CSETBLOCK_SINGLE_OPERATION = 0x1F
cmd = Command:new{cmd = cmds.CMD_MIFARE_CGETBLOCK, arg1 = CSETBLOCK_SINGLE_OPERATION, arg2 = 0, arg3 = blocknum} cmd = Command:new{cmd = cmds.CMD_MIFARE_CGETBLOCK, arg1 = CSETBLOCK_SINGLE_OPERATION, arg2 = 0, arg3 = blocknum}
err = core.SendCommand(cmd:getBytes()) err = core.SendCommand(cmd:getBytes())
@ -89,11 +89,13 @@ local function main(args)
print( string.rep('--',20) ) print( string.rep('--',20) )
local numBlocks = 64 local numBlocks = 64
local cset = 'hf mf csetbl ' local cset = 'hf mf csetbl '
local csetuid = 'hf mf csetuid ' local csetuid = 'hf mf csetuid '
local cget = 'hf mf cgetbl ' local cget = 'hf mf cgetbl '
local empty = '00000000000000000000000000000000' local empty = '00000000000000000000000000000000'
local AccAndKeyB = '7F078869000000000000' local AccAndKeyB = '7F0F0869000000000000'
local atqa = '0F01'
local sak = '81'
-- Defaults to Gusto -- Defaults to Gusto
local toytype = 'C201' local toytype = 'C201'
local subtype = '0030' local subtype = '0030'
@ -107,42 +109,43 @@ local function main(args)
if o == "l" then return toys.List() end if o == "l" then return toys.List() end
end end
if #toytype ~= 4 then return oops('Wrong size - toytype. (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 if #subtype ~= 4 then return oops('[!] Wrong size - subtype. (4hex symbols)') end
-- look up type, find & validate types -- look up type, find & validate types
local item = toys.Find( toytype, subtype) local item = toys.Find( toytype, subtype)
if item then 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 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 end
--15,16 --15,16
--13-14 --13-14
-- find tag -- find tag
result, err = lib14a.read(false, true) result, err = lib14a.read(false, true)
if not result then return oops(err) end if not result then return oops(err) end
-- load keys -- load keys
local akeys = pre.GetAll(result.uid) 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 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) b0, err = readmagicblock(0)
if not b0 then if not b0 then
oops(err) oops('[!] '..err)
return oops('failed reading block with chinese magic command. quitting...') return oops('[!] failed reading block with chinese magic command. Quitting...')
end end
end end
core.clearCommandBuffer()
-- wipe card.
local cmd = (csetuid..'%s 0004 08 w'):format(result.uid)
core.console(cmd)
-- 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 b1 = toytype..string.rep('00',10)..subtype
local calc = utils.Crc16(b0..b1) local calc = utils.Crc16(b0..b1)
@ -150,6 +153,7 @@ local function main(args)
local cmd = (cset..'1 %s%04x'):format( b1, calcEndian) local cmd = (cset..'1 %s%04x'):format( b1, calcEndian)
core.console(cmd) core.console(cmd)
core.clearCommandBuffer()
local pos, key local pos, key
for blockNo = 2, numBlocks-1, 1 do for blockNo = 2, numBlocks-1, 1 do
@ -161,5 +165,10 @@ local function main(args)
end end
end end
core.clearCommandBuffer() 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 end
main(args) main(args)

View file

@ -105,7 +105,7 @@ CborError _cbor_value_dup_string(const CborValue *value, void **buffer, size_t *
return err; return err;
++*buflen; ++*buflen;
*buffer = malloc(*buflen); *buffer = calloc(*buflen, sizeof(uint8_t));
if (!*buffer) { if (!*buffer) {
/* out of memory */ /* out of memory */
return CborErrorOutOfMemory; return CborErrorOutOfMemory;

View file

@ -178,7 +178,7 @@ static CborError dump_bytestring_base16(char **result, CborValue *it)
return err; return err;
/* a Base16 (hex) output is twice as big as our buffer */ /* 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; *result = (char *)buffer;
/* let cbor_value_copy_byte_string know we have an extra byte for the terminating NUL */ /* 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 */ /* a Base64 output (untruncated) has 4 bytes for every 3 in the input */
size_t len = (n + 5) / 3 * 4; 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; *result = (char *)buffer;
/* we read our byte string at the tail end of the buffer /* we read our byte string at the tail end of the buffer

View file

@ -90,7 +90,7 @@ static int close_buffer(void *cookie)
FILE *open_memstream(char **bufptr, size_t *lenptr) 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) if (b == NULL)
return NULL; return NULL;
b->alloc = 0; b->alloc = 0;

View file

@ -196,7 +196,7 @@ void SetFlushAfterWrite(bool value) {
int i,j; int i,j;
int * output = (int* ) malloc(sizeof(int) * len); int * output = (int* ) calloc(sizeof(int) * len, sizeof(uint8_t));
if ( !output ) return; if ( !output ) return;
// clear mem // clear mem

View file

@ -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); printf("(sprint_bin_break) rowlen %d\n", rowlen);
// 3072 + end of line characters if broken at 8 bits // 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; if (dest == NULL) return;
//clear memory //clear memory
@ -884,8 +884,8 @@ extern void strcreplace(char *buf, size_t len, char from, char to) {
} }
extern char *strmcopy(char *buf) { extern char *strmcopy(char *buf) {
char* str = NULL; char* str = (char*) calloc(strlen(buf) + 1, sizeof(uint8_t));
if ((str = (char*) malloc(strlen(buf) + 1)) != NULL) { if (str != NULL) {
memset(str, 0, strlen(buf) + 1); memset(str, 0, strlen(buf) + 1);
strcpy(str, buf); strcpy(str, buf);
} }

View file

@ -178,6 +178,14 @@
} }
#endif #endif
#ifndef DropFieldEx
#define DropFieldEx(x) { \
if ( (x) == ECC_CONTACTLESS) { \
DropField(); \
} \
}
#endif
extern uint8_t g_debugMode; extern uint8_t g_debugMode;
extern int ukbhit(void); extern int ukbhit(void);

View file

@ -405,7 +405,7 @@ int nonce_distance(uint32_t from, uint32_t to)
{ {
uint16_t x, i; uint16_t x, i;
if(!dist) { if(!dist) {
dist = malloc(2 << 16); dist = calloc(2 << 16, sizeof(uint8_t));
if(!dist) if(!dist)
return -1; return -1;
for (x = i = 1; i; ++i) { 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 *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; if (!candidates) return 0;
uint32_t c, entry; uint32_t c, entry;

View file

@ -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 // Christian Herrmann 2018
#ifndef ISO15693_H__ #ifndef ISO15693_H__

View file

@ -302,10 +302,10 @@ ISO 7816-4 Basic interindustry commands. For command APDU's.
#define ISO7816_VERIFY 0x20 #define ISO7816_VERIFY 0x20
#define ISO7816_INTERNAL_AUTHENTICATION 0x88 #define ISO7816_INTERNAL_AUTHENTICATION 0x88
#define ISO7816_EXTERNAL_AUTHENTICATION 0x82 #define ISO7816_EXTERNAL_AUTHENTICATION 0x82
#define ISO7816_GET_CHALLENGE 0xB4 #define ISO7816_GET_CHALLENGE 0x84
#define ISO7816_MANAGE_CHANNEL 0x70 #define ISO7816_MANAGE_CHANNEL 0x70
#define ISO7816_GETSTATUS 0xC0 #define ISO7816_GET_RESPONSE 0xC0
// ISO7816-4 For response APDU's // ISO7816-4 For response APDU's
#define ISO7816_OK 0x9000 #define ISO7816_OK 0x9000
// 6x xx = ERROR // 6x xx = ERROR

View file

@ -3,7 +3,7 @@
uint64_t * radixSort(uint64_t * array, uint32_t size) { uint64_t * radixSort(uint64_t * array, uint32_t size) {
rscounts_t counts; rscounts_t counts;
memset(&counts, 0, 256 * 8 * sizeof(uint32_t)); 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 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 t8, t7, t6, t5, t4, t3, t2, t1;
uint32_t x; uint32_t x;

View file

@ -35,7 +35,8 @@ typedef enum ISO14A_COMMAND {
ISO14A_SET_TIMEOUT = (1 << 6), ISO14A_SET_TIMEOUT = (1 << 6),
ISO14A_NO_SELECT = (1 << 7), ISO14A_NO_SELECT = (1 << 7),
ISO14A_TOPAZMODE = (1 << 8), ISO14A_TOPAZMODE = (1 << 8),
ISO14A_NO_RATS = (1 << 9) ISO14A_NO_RATS = (1 << 9),
ISO14A_SEND_CHAINING = (1 << 10)
} iso14a_command_t; } iso14a_command_t;
typedef struct { typedef struct {

View file

@ -140,6 +140,8 @@ typedef struct{
#define CMD_COTAG 0x0225 #define CMD_COTAG 0x0225
#define CMD_SET_LF_T55XX_CONFIG 0x0226 #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 */ /* CMD_SET_ADC_MUX: ext1 is 0 for lopkd, 1 for loraw, 2 for hipkd, 3 for hiraw */
// For the 13.56 MHz tags // For the 13.56 MHz tags

View file

@ -8,4 +8,12 @@ get_crapto1:
get_nonce_bf: get_nonce_bf:
# git clone https://github.com/J-Run/mf_key_brute.git mf_key_brute # 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 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

View file

@ -28,7 +28,7 @@ my $clean = 2;
# fatal: No names found, cannot describe anything. # fatal: No names found, cannot describe anything.
## ##
# anyway forcing any kind of shell is at least useless, at worst fatal. # 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) ) { if ( defined($commandGIT) ) {

View file

@ -68,14 +68,14 @@ typedef struct {
} serial_port_unix; } serial_port_unix;
// Set time-out on 30 miliseconds // Set time-out on 30 miliseconds
const struct timeval timeout = { struct timeval timeout = {
.tv_sec = 0, // 0 second .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 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 (sp == 0) return INVALID_SERIAL_PORT;
if (memcmp(pcPortName, "tcp:", 4) == 0) { if (memcmp(pcPortName, "tcp:", 4) == 0) {
@ -89,6 +89,10 @@ serial_port uart_open(const char* pcPortName)
char *colon = strrchr(addrstr, ':'); char *colon = strrchr(addrstr, ':');
char *portstr; char *portstr;
// Set time-out to 300 miliseconds only for TCP port
timeout.tv_usec = 300000;
if (colon) { if (colon) {
portstr = colon + 1; portstr = colon + 1;
*colon = '\0'; *colon = '\0';

View file

@ -50,7 +50,7 @@ typedef struct {
serial_port uart_open(const char* pcPortName) { serial_port uart_open(const char* pcPortName) {
char acPortName[255]; 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) { if (sp == 0) {
printf("[!] UART failed to allocate memory\n"); printf("[!] UART failed to allocate memory\n");