mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-19 21:03:48 -07:00
Merge branch 'master' of github.com:merlokk/proxmark3i into emv_vsdc
This commit is contained in:
commit
bebfcab7b9
84 changed files with 3694 additions and 923 deletions
3
.github/ISSUE_TEMPLATE/bug_report.md
vendored
3
.github/ISSUE_TEMPLATE/bug_report.md
vendored
|
@ -1,6 +1,9 @@
|
|||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
|
|
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal 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.
|
|
@ -3,6 +3,9 @@ All notable changes to this project will be documented in this file.
|
|||
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
|
||||
|
||||
## [unreleased][unreleased]
|
||||
- Change 'hf 14a antifuzz' - original implementation (@asfabw), reworked a bit
|
||||
- Fix 'hf mf fchk' (@iceman)
|
||||
- Fix 'usb slow on posix based systems' (@fl0-0)
|
||||
- Change 'lf pcf7931' - improved read code (@sguerrini97)
|
||||
- Change 'hf felica list' - started with some FeliCa annotations (@iceman)
|
||||
- Fix 'hf tune' - now works as expected (@iceman)
|
||||
|
|
88
README.md
88
README.md
|
@ -5,6 +5,33 @@ Proxmark3 RDV40 dedicated repo, based on iceman fork
|
|||
## Notice
|
||||
This repo is based on iceman fork for proxmark3. It is dedicated to bring the most out of the new features for proxmark3 RDV40 device.
|
||||
|
||||
# Donations
|
||||
Nothing says thank you as much as a donation, https://www.patreon.com/iceman1001
|
||||
|
||||
## ToC
|
||||
|
||||
- Coverity Scan Config & Run
|
||||
- Whats changed?
|
||||
- Why didn't you based it on offical PM3 Master?
|
||||
- Why don't you add this or that functionality?
|
||||
- PM3 GUI
|
||||
- Development
|
||||
- KALI and ARCHLINUX users
|
||||
- Setup and build for UBUNTU
|
||||
- Setup and build for ArchLinux
|
||||
- Homebrew (Mac OS X)
|
||||
- Upgrading HomeBrew tap formula
|
||||
- Building on Windows
|
||||
- Gator96100 distro
|
||||
- Build and run
|
||||
- Validating proxmark client functionality
|
||||
- Run the following commands
|
||||
- Quit client
|
||||
- First things on your RDV40
|
||||
- Verify sim module firmware version
|
||||
|
||||
- The end
|
||||
|
||||
## Coverity Scan Config & Run
|
||||
Download the Coverity Scan Self-buld and install it.
|
||||
You will need to configure ARM-NON-EABI- Compiler for it to use:
|
||||
|
@ -37,19 +64,28 @@ The separation from offical pm3 repo gives us very much freedom to create a firm
|
|||
Give us a hint, and we'll see if we can't merge in the stuff you have.
|
||||
|
||||
## PM3 GUI
|
||||
The official PM3-GUI from Gaucho will not work.
|
||||
The new universial GUI will work.
|
||||
The official PM3-GUI from Gaucho will not work.
|
||||
The new universial GUI will work. [Proxmark3 Univerisal GUI](https://github.com/burma69/PM3UniversalGUI)
|
||||
|
||||
## Development
|
||||
This fork now compiles just fine on
|
||||
- Windows/mingw environment with Qt5.6.1 & GCC 4.8
|
||||
- Ubuntu 1404, 1510, 1604, 1804
|
||||
- Mac OS X / Homebrew
|
||||
- ParrotOS
|
||||
- WSL (Windows subsystem linux) on Windows 10
|
||||
- Docker container
|
||||
|
||||
## KALI and ARCHLINUX users
|
||||
Kali and ArchLinux users usually must kill their modem manager in order for the proxmark3 to enumerate properly.
|
||||
`sudo apt remove modemmanager`
|
||||
```sh
|
||||
sudo apt remove modemmanager
|
||||
```
|
||||
or
|
||||
```sh
|
||||
systemctl stop ModemManager
|
||||
systemctl disable ModemManager
|
||||
```
|
||||
|
||||
## Setup and build for UBUNTU
|
||||
GC made updates to allow this to build easily on Ubuntu 14.04.2 LTS, 15.10 or 16.04
|
||||
|
@ -61,7 +97,7 @@ I have also added this script to the fork.
|
|||
https://github.com/RfidResearchGroup/proxmark3/blob/master/install.sh
|
||||
|
||||
- Run
|
||||
`sudo apt-get install p7zip git build-essential libreadline5 libreadline-dev libusb-0.1-4 libusb-dev libqt4-dev perl pkg-config wget libncurses5-dev gcc-arm-none-eabi libjansson-dev`
|
||||
`sudo apt-get install p7zip git build-essential libreadline5 libreadline-dev libusb-0.1-4 libusb-dev libqt4-dev perl pkg-config wget libncurses5-dev gcc-arm-none-eabi`
|
||||
|
||||
- Clone fork
|
||||
`git clone https://github.com/RfidResearchGroup/proxmark3.git`
|
||||
|
@ -86,7 +122,7 @@ https://github.com/RfidResearchGroup/proxmark3/blob/master/install.sh
|
|||
|
||||
## Setup and build for ArchLinux
|
||||
- Run
|
||||
`sudo pacman -Sy base-devel p7zip libusb readline ncurses libjansson-dev arm-none-eabi-newlib --needed`
|
||||
`sudo pacman -Sy base-devel p7zip libusb readline ncurses arm-none-eabi-newlib --needed`
|
||||
`yaourt -S termcap`
|
||||
|
||||
- Remove modemmanager
|
||||
|
@ -224,7 +260,7 @@ If all went well you should get some information about the firmware and memory u
|
|||
>
|
||||
> pm3 -->
|
||||
|
||||
### run the following commands
|
||||
### Run the following commands
|
||||
pm3 --> hw status
|
||||
pm3 --> hw version
|
||||
pm3 --> hw tune
|
||||
|
@ -240,6 +276,46 @@ You are now ready to use your newly upgraded proxmark3 device. Many commands us
|
|||
pm3 --> quit
|
||||
|
||||
|
||||
### First things on your RDV40
|
||||
You will need to run these commands to make sure your rdv4 is prepared
|
||||
|
||||
pm3 --> mem load f default_keys m
|
||||
pm3 --> mem load f default_pwd t
|
||||
pm3 --> mem load f default_iclass_keys i
|
||||
pm3 --> lf t55xx deviceconfig a 29 b 17 c 15 d 47 e 15 p
|
||||
|
||||
### Verify sim module firmware version
|
||||
To make sure you got the latest sim module firmware.
|
||||
_Lastest version is v3.10_
|
||||
|
||||
pm3 --> hw status
|
||||
|
||||
Find version in the long output, look for these two lines
|
||||
|
||||
#db# Smart card module (ISO 7816)
|
||||
#db# version.................v2.06
|
||||
|
||||
This version is obselete. The following command upgrades your device sim module firmware.
|
||||
Don't not turn of your device during the execution of this command.
|
||||
|
||||
pm3 --> sc upgrade f ../tools/simmodule/SIM010.BIN
|
||||
|
||||
You get the following output, this is a successful execution.
|
||||
|
||||
[!] WARNING - Smartcard socket firmware upgrade.
|
||||
[!] A dangerous command, do wrong and you will brick the smart card socket
|
||||
[+] Smartcard socket firmware uploading to PM3
|
||||
..
|
||||
[+] Smartcard socket firmware updating, don't turn off your PM3!
|
||||
#db# FW 0000
|
||||
#db# FW 0080
|
||||
#db# FW 0100
|
||||
#db# FW 0180
|
||||
#db# FW 0200
|
||||
#db# FW 0280
|
||||
[+] Smartcard socket firmware upgraded successful
|
||||
|
||||
|
||||
## the end
|
||||
|
||||
`iceman at host iuse.se`
|
||||
|
|
|
@ -21,7 +21,7 @@ APP_CFLAGS = -DWITH_CRC \
|
|||
-DWITH_ISO14443a \
|
||||
-DWITH_ICLASS \
|
||||
-DWITH_FELICA \
|
||||
-DWITH_FLASH \
|
||||
-DWITH_FLASH \
|
||||
-DWITH_SMARTCARD \
|
||||
-DWITH_FPC \
|
||||
-DWITH_HFSNOOP \
|
||||
|
@ -191,7 +191,7 @@ $(OBJDIR)/fpga_all.bit.z: $(FPGA_BITSTREAMS) $(FPGA_COMPRESSOR)
|
|||
$(FPGA_COMPRESSOR) $(filter %.bit,$^) $@
|
||||
|
||||
$(FPGA_COMPRESSOR):
|
||||
make -C ../client $(notdir $(FPGA_COMPRESSOR))
|
||||
$(MAKE) -C ../client $(notdir $(FPGA_COMPRESSOR))
|
||||
|
||||
$(OBJDIR)/fullimage.stage1.elf: $(VERSIONOBJ) $(OBJDIR)/fpga_all.o $(THUMBOBJ) $(ARMOBJ)
|
||||
$(CC) $(LDFLAGS) -Wl,-T,ldscript,-Map,$(patsubst %.elf,%.map,$@) -o $@ $^ $(LIBS)
|
||||
|
|
|
@ -271,6 +271,11 @@ void RAMFUNC SniffAndStore(uint8_t param) {
|
|||
uint16_t writelen = Flash_WriteData(0, total_data, memoffset + 4 * auth_attempts);
|
||||
if (MF_DBGLEVEL > 1) Dbprintf("[!] Wrote %u bytes into flash mem", writelen);
|
||||
|
||||
// If pwd saved successfully, blink led A three times
|
||||
if (writelen > 0) {
|
||||
SpinErr(0, 200, 5); // blink led A
|
||||
}
|
||||
|
||||
SpinDelay(100);
|
||||
|
||||
// Reset the SPI Baudrate to the default value (24MHz)
|
||||
|
|
|
@ -724,6 +724,9 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
|||
case CMD_T55XX_RESET_READ:
|
||||
T55xxResetRead();
|
||||
break;
|
||||
case CMD_T55XX_CHKPWDS:
|
||||
T55xx_ChkPwds();
|
||||
break;
|
||||
case CMD_PCF7931_READ:
|
||||
ReadPCF7931();
|
||||
break;
|
||||
|
|
|
@ -103,6 +103,8 @@ void T55xxWriteBlock(uint32_t Data, uint8_t Block, uint32_t Pwd, uint8_t PwdMode
|
|||
void T55xxWriteBlockExt(uint32_t Data, uint8_t Block, uint32_t Pwd, uint8_t PwdMode);
|
||||
void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd);
|
||||
void T55xxWakeUp(uint32_t Pwd);
|
||||
void T55xx_ChkPwds(void);
|
||||
|
||||
void TurnReadLFOn(uint32_t delay);
|
||||
void EM4xReadWord(uint8_t addr, uint32_t pwd, uint8_t usepwd);
|
||||
void EM4xWriteWord(uint32_t flag, uint32_t data, uint32_t pwd);
|
||||
|
|
|
@ -108,7 +108,7 @@ int EPA_APDU(uint8_t *apdu, size_t length, uint8_t *response)
|
|||
switch(iso_type)
|
||||
{
|
||||
case 'a':
|
||||
return iso14_apdu(apdu, (uint16_t) length, response, NULL);
|
||||
return iso14_apdu(apdu, (uint16_t) length, false, response, NULL);
|
||||
break;
|
||||
case 'b':
|
||||
return iso14443b_apdu(apdu, length, response);
|
||||
|
|
|
@ -2219,13 +2219,16 @@ b8 b7 b6 b5 b4 b3 b2 b1
|
|||
b5,b6 = 00 - DESELECT
|
||||
11 - WTX
|
||||
*/
|
||||
int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, void *data, uint8_t *res) {
|
||||
int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, bool send_chaining, void *data, uint8_t *res) {
|
||||
uint8_t parity[MAX_PARITY_SIZE] = {0x00};
|
||||
uint8_t real_cmd[cmd_len + 4];
|
||||
|
||||
if (cmd_len) {
|
||||
// ISO 14443 APDU frame: PCB [CID] [NAD] APDU CRC PCB=0x02
|
||||
real_cmd[0] = 0x02; // bnr,nad,cid,chn=0; i-block(0x00)
|
||||
if (send_chaining) {
|
||||
real_cmd[0] |= 0x10;
|
||||
}
|
||||
// put block number into the PCB
|
||||
real_cmd[0] |= iso14_pcb_blocknum;
|
||||
memcpy(real_cmd + 1, cmd, cmd_len);
|
||||
|
@ -2245,7 +2248,7 @@ int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, void *data, uint8_t *res) {
|
|||
return 0; //DATA LINK ERROR
|
||||
} else{
|
||||
// S-Block WTX
|
||||
while((data_bytes[0] & 0xF2) == 0xF2) {
|
||||
while(len && ((data_bytes[0] & 0xF2) == 0xF2)) {
|
||||
uint32_t save_iso14a_timeout = iso14a_get_timeout();
|
||||
// temporarily increase timeout
|
||||
iso14a_set_timeout( MAX((data_bytes[1] & 0x3f) * save_iso14a_timeout, MAX_ISO14A_TIMEOUT) );
|
||||
|
@ -2263,32 +2266,34 @@ int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, void *data, uint8_t *res) {
|
|||
iso14a_set_timeout(save_iso14a_timeout);
|
||||
}
|
||||
|
||||
// if we received an I- or R(ACK)-Block with a block number equal to the
|
||||
// current block number, toggle the current block number
|
||||
// if we received an I- or R(ACK)-Block with a block number equal to the
|
||||
// current block number, toggle the current block number
|
||||
if (len >= 3 // PCB+CRC = 3 bytes
|
||||
&& ((data_bytes[0] & 0xC0) == 0 // I-Block
|
||||
|| (data_bytes[0] & 0xD0) == 0x80) // R-Block with ACK bit set to 0
|
||||
&& (data_bytes[0] & 0x01) == iso14_pcb_blocknum) // equal block numbers
|
||||
{
|
||||
iso14_pcb_blocknum ^= 1;
|
||||
}
|
||||
{
|
||||
iso14_pcb_blocknum ^= 1;
|
||||
}
|
||||
|
||||
// if we received I-block with chaining we need to send ACK and receive another block of data
|
||||
if (res)
|
||||
*res = data_bytes[0];
|
||||
|
||||
// crc check
|
||||
if (len >=3 && !check_crc(CRC_14443_A, data_bytes, len)) {
|
||||
if (len >= 3 && !check_crc(CRC_14443_A, data_bytes, len)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// cut frame byte
|
||||
len -= 1;
|
||||
// memmove(data_bytes, data_bytes + 1, len);
|
||||
for (int i = 0; i < len; i++)
|
||||
data_bytes[i] = data_bytes[i + 1];
|
||||
if (len) {
|
||||
// cut frame byte
|
||||
len -= 1;
|
||||
// memmove(data_bytes, data_bytes + 1, len);
|
||||
for (int i = 0; i < len; i++)
|
||||
data_bytes[i] = data_bytes[i + 1];
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
@ -2338,7 +2343,7 @@ void ReaderIso14443a(UsbCommand *c) {
|
|||
|
||||
if ((param & ISO14A_APDU)) {
|
||||
uint8_t res;
|
||||
arg0 = iso14_apdu(cmd, len, buf, &res);
|
||||
arg0 = iso14_apdu(cmd, len, (param & ISO14A_SEND_CHAINING), buf, &res);
|
||||
cmd_send(CMD_ACK, arg0, res, 0, buf, sizeof(buf));
|
||||
}
|
||||
|
||||
|
|
|
@ -114,7 +114,7 @@ extern void ReaderTransmitPar(uint8_t *frame, uint16_t len, uint8_t *par, uint32
|
|||
extern int ReaderReceive(uint8_t *receivedAnswer, uint8_t *par);
|
||||
|
||||
extern void iso14443a_setup(uint8_t fpga_minor_mode);
|
||||
extern int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, void *data, uint8_t *res);
|
||||
extern int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, bool send_chaining, void *data, uint8_t *res);
|
||||
extern int iso14443a_select_card(uint8_t *uid_ptr, iso14a_card_select_t *resp_data, uint32_t *cuid_ptr, bool anticollision, uint8_t num_cascades, bool no_rats);
|
||||
extern int iso14443a_fast_select_card(uint8_t *uid_ptr, uint8_t num_cascades);
|
||||
extern void iso14a_set_trigger(bool enable);
|
||||
|
|
|
@ -61,7 +61,7 @@ static inline uint8_t rx_byte_from_fpga() {
|
|||
WDT_HIT();
|
||||
|
||||
// wait for byte be become available in rx holding register
|
||||
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
|
||||
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
|
||||
return AT91C_BASE_SSC->SSC_RHR;
|
||||
}
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ static inline uint8_t rx_byte_from_fpga() {
|
|||
// To reduce CPU time the amplitude is approximated by using linear functions:
|
||||
// am = MAX(ABS(i),ABS(q)) + 1/2*MIN(ABS(i),ABSq))
|
||||
//
|
||||
// Note: The SSC receiver is never synchronized the calculation my be performed
|
||||
// Note: The SSC receiver is never synchronized the calculation may be performed
|
||||
// on a i/q pair from two subsequent correlations, but does not matter.
|
||||
static inline int32_t sample_power() {
|
||||
int32_t q = (int8_t)rx_byte_from_fpga(); q = ABS(q);
|
||||
|
@ -100,7 +100,7 @@ static inline int32_t sample_power() {
|
|||
static inline bool rx_bit() {
|
||||
int32_t power;
|
||||
|
||||
for(size_t i = 0; i<5; ++i) {
|
||||
for (size_t i = 0; i<5; ++i) {
|
||||
power = sample_power();
|
||||
}
|
||||
|
||||
|
@ -120,12 +120,12 @@ static inline void tx_bit(bool bit) {
|
|||
// insert pause
|
||||
LOW(GPIO_SSC_DOUT);
|
||||
last_frame_end += RWD_TIME_PAUSE;
|
||||
while(GET_TICKS < last_frame_end) { };
|
||||
while (GET_TICKS < last_frame_end) { };
|
||||
HIGH(GPIO_SSC_DOUT);
|
||||
|
||||
// return to high, wait for bit periode to end
|
||||
last_frame_end += (bit ? RWD_TIME_1 : RWD_TIME_0) - RWD_TIME_PAUSE;
|
||||
while(GET_TICKS < last_frame_end) { };
|
||||
while (GET_TICKS < last_frame_end) { };
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -143,13 +143,13 @@ static void tx_frame(uint32_t frame, uint8_t len) {
|
|||
|
||||
// wait for next tx timeslot
|
||||
last_frame_end += RWD_FRAME_WAIT;
|
||||
while(GET_TICKS < last_frame_end) { };
|
||||
while (GET_TICKS < last_frame_end) { };
|
||||
|
||||
// backup ts for trace log
|
||||
uint32_t last_frame_start = last_frame_end;
|
||||
|
||||
// transmit frame, MSB first
|
||||
for(uint8_t i = 0; i < len; ++i) {
|
||||
for (uint8_t i = 0; i < len; ++i) {
|
||||
bool bit = (frame >> i) & 0x01;
|
||||
tx_bit(bit ^ legic_prng_get_bit());
|
||||
legic_prng_forward(1);
|
||||
|
@ -158,7 +158,7 @@ static void tx_frame(uint32_t frame, uint8_t len) {
|
|||
// add pause to mark end of the frame
|
||||
LOW(GPIO_SSC_DOUT);
|
||||
last_frame_end += RWD_TIME_PAUSE;
|
||||
while(GET_TICKS < last_frame_end) { };
|
||||
while (GET_TICKS < last_frame_end) { };
|
||||
HIGH(GPIO_SSC_DOUT);
|
||||
|
||||
// log
|
||||
|
@ -173,19 +173,19 @@ static uint32_t rx_frame(uint8_t len) {
|
|||
|
||||
// hold sampling until card is expected to respond
|
||||
last_frame_end += TAG_FRAME_WAIT;
|
||||
while(GET_TICKS < last_frame_end) { };
|
||||
while (GET_TICKS < last_frame_end) { };
|
||||
|
||||
// backup ts for trace log
|
||||
uint32_t last_frame_start = last_frame_end;
|
||||
|
||||
uint32_t frame = 0;
|
||||
for(uint8_t i = 0; i < len; ++i) {
|
||||
for (uint8_t i = 0; i < len; ++i) {
|
||||
frame |= (rx_bit() ^ legic_prng_get_bit()) << i;
|
||||
legic_prng_forward(1);
|
||||
|
||||
// rx_bit runs only 95us, resync to TAG_BIT_PERIOD
|
||||
last_frame_end += TAG_BIT_PERIOD;
|
||||
while(GET_TICKS < last_frame_end) { };
|
||||
while (GET_TICKS < last_frame_end) { };
|
||||
}
|
||||
|
||||
// log
|
||||
|
@ -203,23 +203,23 @@ static bool rx_ack() {
|
|||
|
||||
// hold sampling until card is expected to respond
|
||||
last_frame_end += TAG_FRAME_WAIT;
|
||||
while(GET_TICKS < last_frame_end) { };
|
||||
while (GET_TICKS < last_frame_end) { };
|
||||
|
||||
// backup ts for trace log
|
||||
uint32_t last_frame_start = last_frame_end;
|
||||
|
||||
uint32_t ack = 0;
|
||||
for(uint8_t i = 0; i < TAG_WRITE_TIMEOUT; ++i) {
|
||||
for (uint8_t i = 0; i < TAG_WRITE_TIMEOUT; ++i) {
|
||||
// sample bit
|
||||
ack = rx_bit();
|
||||
legic_prng_forward(1);
|
||||
|
||||
// rx_bit runs only 95us, resync to TAG_BIT_PERIOD
|
||||
last_frame_end += TAG_BIT_PERIOD;
|
||||
while(GET_TICKS < last_frame_end) { };
|
||||
while (GET_TICKS < last_frame_end) { };
|
||||
|
||||
// check if it was an ACK
|
||||
if(ack) {
|
||||
if (ack) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -282,7 +282,7 @@ static void init_reader(bool clear_mem) {
|
|||
|
||||
// reserve a cardmem, meaning we can use the tracelog function in bigbuff easier.
|
||||
legic_mem = BigBuf_get_EM_addr();
|
||||
if(legic_mem) {
|
||||
if (legic_mem) {
|
||||
memset(legic_mem, 0x00, LEGIC_CARD_MEMSIZE);
|
||||
}
|
||||
|
||||
|
@ -309,7 +309,7 @@ static uint32_t setup_phase(uint8_t iv) {
|
|||
|
||||
// Switch on carrier and let the card charge for 5ms.
|
||||
last_frame_end += 7500;
|
||||
while(GET_TICKS < last_frame_end) { };
|
||||
while (GET_TICKS < last_frame_end) { };
|
||||
|
||||
legic_prng_init(0);
|
||||
tx_frame(iv, 7);
|
||||
|
@ -359,7 +359,7 @@ static int16_t read_byte(uint16_t index, uint8_t cmd_sz) {
|
|||
|
||||
// check received against calculated crc
|
||||
uint8_t calc_crc = calc_crc4(cmd, cmd_sz, byte);
|
||||
if(calc_crc != crc) {
|
||||
if (calc_crc != crc) {
|
||||
Dbprintf("!!! crc mismatch: %x != %x !!!", calc_crc, crc);
|
||||
return -1;
|
||||
}
|
||||
|
@ -399,15 +399,15 @@ void LegicRfInfo(void) {
|
|||
|
||||
// establish shared secret and detect card type
|
||||
uint8_t card_type = setup_phase(0x01);
|
||||
if(init_card(card_type, &card) != 0) {
|
||||
if (init_card(card_type, &card) != 0) {
|
||||
cmd_send(CMD_ACK, 0, 0, 0, 0, 0);
|
||||
goto OUT;
|
||||
}
|
||||
|
||||
// read UID
|
||||
for(uint8_t i = 0; i < sizeof(card.uid); ++i) {
|
||||
for (uint8_t i = 0; i < sizeof(card.uid); ++i) {
|
||||
int16_t byte = read_byte(i, card.cmdsize);
|
||||
if(byte == -1) {
|
||||
if (byte == -1) {
|
||||
cmd_send(CMD_ACK, 0, 0, 0, 0, 0);
|
||||
goto OUT;
|
||||
}
|
||||
|
@ -417,7 +417,7 @@ void LegicRfInfo(void) {
|
|||
// read MCC and check against UID
|
||||
int16_t mcc = read_byte(4, card.cmdsize);
|
||||
int16_t calc_mcc = CRC8Legic(card.uid, 4);;
|
||||
if(mcc != calc_mcc) {
|
||||
if (mcc != calc_mcc) {
|
||||
cmd_send(CMD_ACK, 0, 0, 0, 0, 0);
|
||||
goto OUT;
|
||||
}
|
||||
|
@ -436,19 +436,19 @@ void LegicRfReader(uint16_t offset, uint16_t len, uint8_t iv) {
|
|||
|
||||
// establish shared secret and detect card type
|
||||
uint8_t card_type = setup_phase(iv);
|
||||
if(init_card(card_type, &card) != 0) {
|
||||
if (init_card(card_type, &card) != 0) {
|
||||
cmd_send(CMD_ACK, 0, 0, 0, 0, 0);
|
||||
goto OUT;
|
||||
}
|
||||
|
||||
// do not read beyond card memory
|
||||
if(len + offset > card.cardsize) {
|
||||
if (len + offset > card.cardsize) {
|
||||
len = card.cardsize - offset;
|
||||
}
|
||||
|
||||
for(uint16_t i = 0; i < len; ++i) {
|
||||
for (uint16_t i = 0; i < len; ++i) {
|
||||
int16_t byte = read_byte(offset + i, card.cmdsize);
|
||||
if(byte == -1) {
|
||||
if (byte == -1) {
|
||||
cmd_send(CMD_ACK, 0, 0, 0, 0, 0);
|
||||
goto OUT;
|
||||
}
|
||||
|
@ -468,26 +468,26 @@ void LegicRfWriter(uint16_t offset, uint16_t len, uint8_t iv, uint8_t *data) {
|
|||
init_reader(false);
|
||||
|
||||
// uid is not writeable
|
||||
if(offset <= WRITE_LOWERLIMIT) {
|
||||
if (offset <= WRITE_LOWERLIMIT) {
|
||||
cmd_send(CMD_ACK, 0, 0, 0, 0, 0);
|
||||
goto OUT;
|
||||
}
|
||||
|
||||
// establish shared secret and detect card type
|
||||
uint8_t card_type = setup_phase(iv);
|
||||
if(init_card(card_type, &card) != 0) {
|
||||
if (init_card(card_type, &card) != 0) {
|
||||
cmd_send(CMD_ACK, 0, 0, 0, 0, 0);
|
||||
goto OUT;
|
||||
}
|
||||
|
||||
// do not write beyond card memory
|
||||
if(len + offset > card.cardsize) {
|
||||
if (len + offset > card.cardsize) {
|
||||
len = card.cardsize - offset;
|
||||
}
|
||||
|
||||
// write in reverse order, only then is DCF (decremental field) writable
|
||||
while(len-- > 0 && !BUTTON_PRESS()) {
|
||||
if(!write_byte(len + offset, data[len], card.addrsize)) {
|
||||
while (len-- > 0 && !BUTTON_PRESS()) {
|
||||
if (!write_byte(len + offset, data[len], card.addrsize)) {
|
||||
Dbprintf("operation failed | %02X | %02X | %02X", len + offset, len, data[len]);
|
||||
cmd_send(CMD_ACK, 0, 0, 0, 0, 0);
|
||||
goto OUT;
|
||||
|
|
|
@ -46,7 +46,7 @@ static uint32_t last_frame_end; /* ts of last bit of previews rx or tx frame */
|
|||
#define RWD_TIME_PAUSE 4 /* 18.9us */
|
||||
#define RWD_TIME_1 21 /* RWD_TIME_PAUSE 18.9us off + 80.2us on = 99.1us */
|
||||
#define RWD_TIME_0 13 /* RWD_TIME_PAUSE 18.9us off + 42.4us on = 61.3us */
|
||||
#define RWD_CMD_TIMEOUT 40 /* 40 * 99.1us (arbitrary value) */
|
||||
#define RWD_CMD_TIMEOUT 120 /* 120 * 99.1us (arbitrary value) */
|
||||
#define RWD_MIN_FRAME_LEN 6 /* Shortest frame is 6 bits */
|
||||
#define RWD_MAX_FRAME_LEN 23 /* Longest frame is 23 bits */
|
||||
|
||||
|
@ -59,8 +59,8 @@ static uint32_t last_frame_end; /* ts of last bit of previews rx or tx frame */
|
|||
|
||||
// Returns true if a pulse/pause is received within timeout
|
||||
static inline bool wait_for(bool value, const uint32_t timeout) {
|
||||
while((bool)(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_DIN) != value) {
|
||||
if(GetCountSspClk() > timeout) {
|
||||
while ((bool)(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_DIN) != value) {
|
||||
if (GetCountSspClk() > timeout) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -81,12 +81,12 @@ static inline int8_t rx_bit() {
|
|||
uint32_t bit_start = last_frame_end;
|
||||
|
||||
// wait for pause to end
|
||||
if(!wait_for(RWD_PULSE, bit_start + RWD_TIME_1*3/2)) {
|
||||
if (!wait_for(RWD_PULSE, bit_start + RWD_TIME_1*3/2)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// wait for next pause
|
||||
if(!wait_for(RWD_PAUSE, bit_start + RWD_TIME_1*3/2)) {
|
||||
if (!wait_for(RWD_PAUSE, bit_start + RWD_TIME_1*3/2)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -94,7 +94,7 @@ static inline int8_t rx_bit() {
|
|||
last_frame_end = GetCountSspClk();
|
||||
|
||||
// check for code violation (bit to short)
|
||||
if(last_frame_end - bit_start < RWD_TIME_PAUSE) {
|
||||
if (last_frame_end - bit_start < RWD_TIME_PAUSE) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -122,7 +122,7 @@ static inline int8_t rx_bit() {
|
|||
static inline void tx_bit(bool bit) {
|
||||
LED_C_ON();
|
||||
|
||||
if(bit) {
|
||||
if (bit) {
|
||||
// modulate subcarrier
|
||||
HIGH(GPIO_SSC_DOUT);
|
||||
} else {
|
||||
|
@ -132,7 +132,7 @@ static inline void tx_bit(bool bit) {
|
|||
|
||||
// wait for tx timeslot to end
|
||||
last_frame_end += TAG_BIT_PERIOD;
|
||||
while(GetCountSspClk() < last_frame_end) { };
|
||||
while (GetCountSspClk() < last_frame_end) { };
|
||||
LED_C_OFF();
|
||||
}
|
||||
|
||||
|
@ -150,13 +150,13 @@ static void tx_frame(uint32_t frame, uint8_t len) {
|
|||
// wait for next tx timeslot
|
||||
last_frame_end += TAG_FRAME_WAIT;
|
||||
legic_prng_forward(TAG_FRAME_WAIT/TAG_BIT_PERIOD - 1);
|
||||
while(GetCountSspClk() < last_frame_end) { };
|
||||
while (GetCountSspClk() < last_frame_end) { };
|
||||
|
||||
// backup ts for trace log
|
||||
uint32_t last_frame_start = last_frame_end;
|
||||
|
||||
// transmit frame, MSB first
|
||||
for(uint8_t i = 0; i < len; ++i) {
|
||||
for (uint8_t i = 0; i < len; ++i) {
|
||||
bool bit = (frame >> i) & 0x01;
|
||||
tx_bit(bit ^ legic_prng_get_bit());
|
||||
legic_prng_forward(1);
|
||||
|
@ -174,7 +174,7 @@ static void tx_ack() {
|
|||
// wait for ack timeslot
|
||||
last_frame_end += TAG_ACK_WAIT;
|
||||
legic_prng_forward(TAG_ACK_WAIT/TAG_BIT_PERIOD - 1);
|
||||
while(GetCountSspClk() < last_frame_end) { };
|
||||
while (GetCountSspClk() < last_frame_end) { };
|
||||
|
||||
// backup ts for trace log
|
||||
uint32_t last_frame_start = last_frame_end;
|
||||
|
@ -206,19 +206,19 @@ static int32_t rx_frame(uint8_t *len) {
|
|||
last_frame_end -= 2;
|
||||
|
||||
// wait for first pause (start of frame)
|
||||
for(uint8_t i = 0; true; ++i) {
|
||||
for (uint8_t i = 0; true; ++i) {
|
||||
// increment prng every TAG_BIT_PERIOD
|
||||
last_frame_end += TAG_BIT_PERIOD;
|
||||
legic_prng_forward(1);
|
||||
|
||||
// if start of frame was received exit delay loop
|
||||
if(wait_for(RWD_PAUSE, last_frame_end)) {
|
||||
if (wait_for(RWD_PAUSE, last_frame_end)) {
|
||||
last_frame_end = GetCountSspClk();
|
||||
break;
|
||||
}
|
||||
|
||||
// check for code violation
|
||||
if(i > RWD_CMD_TIMEOUT) {
|
||||
if (i > RWD_CMD_TIMEOUT) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -227,19 +227,19 @@ static int32_t rx_frame(uint8_t *len) {
|
|||
uint32_t last_frame_start = last_frame_end;
|
||||
|
||||
// receive frame
|
||||
for(*len = 0; true; ++(*len)) {
|
||||
for (*len = 0; true; ++(*len)) {
|
||||
// receive next bit
|
||||
LED_B_ON();
|
||||
int8_t bit = rx_bit();
|
||||
LED_B_OFF();
|
||||
|
||||
// check for code violation and to short / long frame
|
||||
if((bit < 0) && ((*len < RWD_MIN_FRAME_LEN) || (*len > RWD_MAX_FRAME_LEN))) {
|
||||
if ((bit < 0) && ((*len < RWD_MIN_FRAME_LEN) || (*len > RWD_MAX_FRAME_LEN))) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// check for code violation caused by end of frame
|
||||
if(bit < 0) {
|
||||
if (bit < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -256,7 +256,6 @@ static int32_t rx_frame(uint8_t *len) {
|
|||
// log
|
||||
uint8_t cmdbytes[] = {*len, BYTEx(frame, 0), BYTEx(frame, 1), BYTEx(frame, 2)};
|
||||
LogTrace(cmdbytes, sizeof(cmdbytes), last_frame_start, last_frame_end, NULL, true);
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
|
@ -267,7 +266,7 @@ static int32_t rx_frame(uint8_t *len) {
|
|||
static int32_t init_card(uint8_t cardtype, legic_card_select_t *p_card) {
|
||||
p_card->tagtype = cardtype;
|
||||
|
||||
switch(p_card->tagtype) {
|
||||
switch (p_card->tagtype) {
|
||||
case 0:
|
||||
p_card->cmdsize = 6;
|
||||
p_card->addrsize = 5;
|
||||
|
@ -338,7 +337,7 @@ static int32_t setup_phase(legic_card_select_t *p_card) {
|
|||
|
||||
// wait for iv
|
||||
int32_t iv = rx_frame(&len);
|
||||
if((len != 7) || (iv < 0)) {
|
||||
if ((len != 7) || (iv < 0)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -346,7 +345,7 @@ static int32_t setup_phase(legic_card_select_t *p_card) {
|
|||
legic_prng_init(iv);
|
||||
|
||||
// reply with card type
|
||||
switch(p_card->tagtype) {
|
||||
switch (p_card->tagtype) {
|
||||
case 0:
|
||||
tx_frame(0x0D, 6);
|
||||
break;
|
||||
|
@ -360,12 +359,12 @@ static int32_t setup_phase(legic_card_select_t *p_card) {
|
|||
|
||||
// wait for ack
|
||||
int32_t ack = rx_frame(&len);
|
||||
if((len != 6) || (ack < 0)) {
|
||||
if ((len != 6) || (ack < 0)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// validate data
|
||||
switch(p_card->tagtype) {
|
||||
switch (p_card->tagtype) {
|
||||
case 0:
|
||||
if(ack != 0x19) return -1;
|
||||
break;
|
||||
|
@ -399,12 +398,12 @@ static int32_t connected_phase(legic_card_select_t *p_card) {
|
|||
|
||||
// wait for command
|
||||
int32_t cmd = rx_frame(&len);
|
||||
if(cmd < 0) {
|
||||
if (cmd < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// check if command is LEGIC_READ
|
||||
if(len == p_card->cmdsize) {
|
||||
if (len == p_card->cmdsize) {
|
||||
// prepare data
|
||||
uint8_t byte = legic_mem[cmd >> 1];
|
||||
uint8_t crc = calc_crc4(cmd, p_card->cmdsize, byte);
|
||||
|
@ -416,7 +415,7 @@ static int32_t connected_phase(legic_card_select_t *p_card) {
|
|||
}
|
||||
|
||||
// check if command is LEGIC_WRITE
|
||||
if(len == p_card->cmdsize + 8 + 4) {
|
||||
if (len == p_card->cmdsize + 8 + 4) {
|
||||
// decode data
|
||||
uint16_t mask = (1 << p_card->addrsize) - 1;
|
||||
uint16_t addr = (cmd >> 1) & mask;
|
||||
|
@ -425,7 +424,7 @@ static int32_t connected_phase(legic_card_select_t *p_card) {
|
|||
|
||||
// check received against calculated crc
|
||||
uint8_t calc_crc = calc_crc4(addr << 1, p_card->cmdsize, byte);
|
||||
if(calc_crc != crc) {
|
||||
if (calc_crc != crc) {
|
||||
Dbprintf("!!! crc mismatch: %x != %x !!!", calc_crc, crc);
|
||||
return -1;
|
||||
}
|
||||
|
@ -453,7 +452,7 @@ void LegicRfSimulate(uint8_t cardtype) {
|
|||
init_tag();
|
||||
|
||||
// verify command line input
|
||||
if(init_card(cardtype, &card) != 0) {
|
||||
if (init_card(cardtype, &card) != 0) {
|
||||
DbpString("Unknown tagtype.");
|
||||
goto OUT;
|
||||
}
|
||||
|
@ -464,17 +463,17 @@ void LegicRfSimulate(uint8_t cardtype) {
|
|||
WDT_HIT();
|
||||
|
||||
// wait for carrier, restart after timeout
|
||||
if(!wait_for(RWD_PULSE, GetCountSspClk() + TAG_BIT_PERIOD)) {
|
||||
if (!wait_for(RWD_PULSE, GetCountSspClk() + TAG_BIT_PERIOD)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// wait for connection, restart on error
|
||||
if(setup_phase(&card)) {
|
||||
if (setup_phase(&card)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// conection is established, process commands until one fails
|
||||
while(!connected_phase(&card)) {
|
||||
while (!connected_phase(&card)) {
|
||||
WDT_HIT();
|
||||
}
|
||||
}
|
||||
|
|
186
armsrc/lfops.c
186
armsrc/lfops.c
|
@ -80,7 +80,7 @@ void setT55xxConfig(uint8_t arg0, t55xx_config *c) {
|
|||
|
||||
printT55xxConfig();
|
||||
|
||||
#if WITH_FLASH
|
||||
#ifdef WITH_FLASH
|
||||
// shall persist to flashmem
|
||||
if (arg0 == 0) {
|
||||
return;
|
||||
|
@ -119,7 +119,7 @@ t55xx_config* getT55xxConfig(void) {
|
|||
}
|
||||
|
||||
void loadT55xxConfig(void) {
|
||||
#if WITH_FLASH
|
||||
#ifdef WITH_FLASH
|
||||
if (!FlashInit()) {
|
||||
return;
|
||||
}
|
||||
|
@ -598,9 +598,11 @@ void SimulateTagLowFrequencyEx(int period, int gap, int ledcontrol, int numcycle
|
|||
AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT | GPIO_SSC_CLK;
|
||||
AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT;
|
||||
AT91C_BASE_PIOA->PIO_ODR = GPIO_SSC_CLK;
|
||||
|
||||
uint8_t check = 1;
|
||||
|
||||
for(;;) {
|
||||
|
||||
|
||||
if ( numcycles > -1 ) {
|
||||
if ( x != numcycles ) {
|
||||
++x;
|
||||
|
@ -616,9 +618,11 @@ void SimulateTagLowFrequencyEx(int period, int gap, int ledcontrol, int numcycle
|
|||
// used as a simple detection of a reader field?
|
||||
while (!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) {
|
||||
WDT_HIT();
|
||||
if ( usb_poll_validate_length() || BUTTON_PRESS() )
|
||||
goto OUT;
|
||||
}
|
||||
if ( !check ) {
|
||||
if ( usb_poll_validate_length() || BUTTON_PRESS() )
|
||||
goto OUT;
|
||||
}
|
||||
++check; }
|
||||
|
||||
if (buf[i])
|
||||
OPEN_COIL();
|
||||
|
@ -628,9 +632,11 @@ void SimulateTagLowFrequencyEx(int period, int gap, int ledcontrol, int numcycle
|
|||
//wait until SSC_CLK goes LOW
|
||||
while (AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK) {
|
||||
WDT_HIT();
|
||||
//if ( usb_poll_validate_length() || BUTTON_PRESS() )
|
||||
if ( BUTTON_PRESS() )
|
||||
goto OUT;
|
||||
if ( !check ) {
|
||||
if ( usb_poll_validate_length() || BUTTON_PRESS() )
|
||||
goto OUT;
|
||||
}
|
||||
++check;
|
||||
}
|
||||
|
||||
i++;
|
||||
|
@ -1489,11 +1495,22 @@ void T55xxWriteBlock(uint32_t Data, uint8_t Block, uint32_t Pwd, uint8_t arg) {
|
|||
// Read one card block in page [page]
|
||||
void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd) {
|
||||
LED_A_ON();
|
||||
bool PwdMode = arg0 & 0x1;
|
||||
uint8_t Page = (arg0 & 0x2) >> 1;
|
||||
uint32_t i = 0;
|
||||
bool RegReadMode = (Block == 0xFF);//regular read mode
|
||||
bool PwdMode = arg0 & 0x1;
|
||||
uint8_t Page = ( arg0 & 0x2 ) >> 1;
|
||||
bool brute_mem = arg0 & 0x4;
|
||||
|
||||
uint32_t i = 0;
|
||||
|
||||
// regular read mode
|
||||
bool RegReadMode = (Block == 0xFF);
|
||||
|
||||
uint8_t start_wait = 4;
|
||||
size_t samples = 12000;
|
||||
if ( brute_mem ) {
|
||||
start_wait = 0;
|
||||
samples = 1024;
|
||||
}
|
||||
|
||||
//clear buffer now so it does not interfere with timing later
|
||||
BigBuf_Clear_keep_EM();
|
||||
|
||||
|
@ -1505,7 +1522,8 @@ void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd) {
|
|||
// Set up FPGA, 125kHz to power up the tag
|
||||
LFSetupFPGAForADC(95, true);
|
||||
// make sure tag is fully powered up...
|
||||
WaitMS(4);
|
||||
WaitMS(start_wait);
|
||||
|
||||
// Trigger T55x7 Direct Access Mode with start gap
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
WaitUS(t_config.start_gap);
|
||||
|
@ -1529,17 +1547,118 @@ void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd) {
|
|||
|
||||
// Turn field on to read the response
|
||||
// 137*8 seems to get to the start of data pretty well...
|
||||
// but we want to go past the start and let the repeating data settle in...
|
||||
TurnReadLFOn(210*8);
|
||||
// but we want to go past the start and let the repeating data settle in...
|
||||
TurnReadLFOn(200*8);
|
||||
|
||||
// Acquisition
|
||||
// Now do the acquisition
|
||||
DoPartialAcquisition(0, true, 12000, 0);
|
||||
DoPartialAcquisition(0, true, samples, 0);
|
||||
|
||||
// Turn the field off
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
|
||||
cmd_send(CMD_ACK,0,0,0,0,0);
|
||||
LED_A_OFF();
|
||||
if ( !brute_mem ) {
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
cmd_send(CMD_ACK,0,0,0,0,0);
|
||||
LED_A_OFF();
|
||||
}
|
||||
}
|
||||
|
||||
void T55xx_ChkPwds() {
|
||||
|
||||
DbpString("[+] T55XX Check pwds using flashmemory starting");
|
||||
|
||||
uint8_t ret = 0;
|
||||
// First get baseline and setup LF mode.
|
||||
// tends to mess up BigBuf
|
||||
uint8_t *buf = BigBuf_get_addr();
|
||||
|
||||
uint32_t b1, baseline = 0;
|
||||
|
||||
// collect baseline for failed attempt
|
||||
uint8_t x = 32;
|
||||
while (x--) {
|
||||
b1 = 0;
|
||||
T55xxReadBlock(4, 1, 0);
|
||||
for (uint16_t j=0; j < 1024; ++j)
|
||||
b1 += buf[j];
|
||||
|
||||
b1 *= b1;
|
||||
b1 >>= 8;
|
||||
baseline += b1;
|
||||
}
|
||||
|
||||
baseline >>= 5;
|
||||
Dbprintf("[=] Baseline determined [%u]", baseline);
|
||||
|
||||
|
||||
uint8_t *pwds = BigBuf_get_EM_addr();
|
||||
uint16_t pwdCount = 0;
|
||||
uint32_t candidate = 0;
|
||||
|
||||
#ifdef WITH_FLASH
|
||||
bool use_flashmem = true;
|
||||
if ( use_flashmem ) {
|
||||
BigBuf_Clear_EM();
|
||||
uint16_t isok = 0;
|
||||
uint8_t counter[2] = {0x00, 0x00};
|
||||
isok = Flash_ReadData(DEFAULT_T55XX_KEYS_OFFSET, counter, sizeof(counter) );
|
||||
if ( isok != sizeof(counter) )
|
||||
goto OUT;
|
||||
|
||||
pwdCount = counter[1] << 8 | counter[0];
|
||||
|
||||
if ( pwdCount == 0 && pwdCount == 0xFFFF)
|
||||
goto OUT;
|
||||
|
||||
isok = Flash_ReadData(DEFAULT_T55XX_KEYS_OFFSET+2, pwds, pwdCount * 4);
|
||||
if ( isok != pwdCount * 4 )
|
||||
goto OUT;
|
||||
|
||||
Dbprintf("[=] Password dictionary count %d ", pwdCount);
|
||||
}
|
||||
#endif
|
||||
|
||||
uint32_t pwd = 0, curr = 0, prev = 0;
|
||||
for (uint16_t i =0; i< pwdCount; ++i) {
|
||||
|
||||
if (BUTTON_PRESS() && !usb_poll_validate_length()) {
|
||||
goto OUT;
|
||||
}
|
||||
|
||||
pwd = bytes_to_num(pwds + i * 4, 4);
|
||||
|
||||
|
||||
T55xxReadBlock(5, 0, pwd);
|
||||
|
||||
// calc mean of BigBuf 1024 samples.
|
||||
uint32_t sum = 0;
|
||||
for (uint16_t j=0; j<1024; ++j) {
|
||||
sum += buf[j];
|
||||
}
|
||||
|
||||
sum *= sum;
|
||||
sum >>= 8;
|
||||
|
||||
int32_t tmp = (sum - baseline);
|
||||
curr = ABS(tmp);
|
||||
|
||||
Dbprintf("[=] Pwd %08X | ABS %u", pwd, curr );
|
||||
|
||||
if ( curr > prev ) {
|
||||
|
||||
|
||||
Dbprintf("[=] --> ABS %u Candidate %08X <--", curr, pwd );
|
||||
candidate = pwd;
|
||||
prev = curr;
|
||||
}
|
||||
}
|
||||
|
||||
if ( candidate )
|
||||
ret = 1;
|
||||
|
||||
OUT:
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
cmd_send(CMD_ACK,ret,candidate,0,0,0);
|
||||
LEDsoff();
|
||||
}
|
||||
|
||||
void T55xxWakeUp(uint32_t Pwd){
|
||||
|
@ -1970,7 +2089,6 @@ void EM4xWriteWord(uint32_t flag, uint32_t data, uint32_t pwd) {
|
|||
//Wait 20ms for write to complete?
|
||||
WaitMS(7);
|
||||
|
||||
//Capture response if one exists
|
||||
DoPartialAcquisition(20, true, 6000, 1000);
|
||||
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
|
@ -1994,7 +2112,7 @@ This triggers a COTAG tag to response
|
|||
*/
|
||||
void Cotag(uint32_t arg0) {
|
||||
#ifndef OFF
|
||||
# define OFF { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); WaitUS(2035); }
|
||||
# define OFF(x) { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); WaitUS((x)); }
|
||||
#endif
|
||||
#ifndef ON
|
||||
# define ON(x) { FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); WaitUS((x)); }
|
||||
|
@ -2003,29 +2121,15 @@ void Cotag(uint32_t arg0) {
|
|||
|
||||
LED_A_ON();
|
||||
|
||||
// Switching to LF image on FPGA. This might empty BigBuff
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||
|
||||
LFSetupFPGAForADC(89, true);
|
||||
|
||||
//clear buffer now so it does not interfere with timing later
|
||||
BigBuf_Clear_ext(false);
|
||||
|
||||
// Set up FPGA, 132kHz to power up the tag
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 89);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
|
||||
|
||||
// Connect the A/D to the peak-detected low-frequency path.
|
||||
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
|
||||
|
||||
// Now set up the SSC to get the ADC samples that are now streaming at us.
|
||||
FpgaSetupSsc();
|
||||
|
||||
// start clock - 1.5ticks is 1us
|
||||
StartTicks();
|
||||
|
||||
//send COTAG start pulse
|
||||
ON(740) OFF
|
||||
ON(3330) OFF
|
||||
ON(740) OFF
|
||||
ON(740) OFF(2035)
|
||||
ON(3330) OFF(2035)
|
||||
ON(740) OFF(2035)
|
||||
ON(1000)
|
||||
|
||||
switch(rawsignal) {
|
||||
|
|
|
@ -117,21 +117,21 @@ void LFSetupFPGAForADC(int divisor, bool lf_field) {
|
|||
* @return the number of bits occupied by the samples.
|
||||
*/
|
||||
uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averaging, int trigger_threshold, bool silent, int bufsize, uint32_t cancel_after) {
|
||||
//bigbuf, to hold the aquired raw data signal
|
||||
|
||||
uint8_t *dest = BigBuf_get_addr();
|
||||
bufsize = (bufsize > 0 && bufsize < BigBuf_max_traceLen()) ? bufsize : BigBuf_max_traceLen();
|
||||
|
||||
|
||||
if (bits_per_sample < 1) bits_per_sample = 1;
|
||||
if (bits_per_sample > 8) bits_per_sample = 8;
|
||||
|
||||
if (decimation < 1) decimation = 1;
|
||||
|
||||
// Use a bit stream to handle the output
|
||||
// use a bit stream to handle the output
|
||||
BitstreamOut data = { dest , 0, 0};
|
||||
int sample_counter = 0;
|
||||
uint8_t sample = 0;
|
||||
//If we want to do averaging
|
||||
|
||||
// if we want to do averaging
|
||||
uint32_t sample_sum =0 ;
|
||||
uint32_t sample_total_numbers = 0;
|
||||
uint32_t sample_total_saved = 0;
|
||||
|
@ -139,13 +139,13 @@ uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averag
|
|||
|
||||
while (!BUTTON_PRESS() && !usb_poll_validate_length() ) {
|
||||
WDT_HIT();
|
||||
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
|
||||
AT91C_BASE_SSC->SSC_THR = 0x43;
|
||||
LED_D_ON();
|
||||
}
|
||||
|
||||
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
|
||||
sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||
|
||||
// Testpoint 8 (TP8) can be used to trigger oscilliscope
|
||||
LED_D_OFF();
|
||||
|
||||
// threshold either high or low values 128 = center 0. if trigger = 178
|
||||
if ((trigger_threshold > 0) && (sample < (trigger_threshold + 128)) && (sample > (128 - trigger_threshold))) {
|
||||
if (cancel_after > 0) {
|
||||
|
@ -162,24 +162,26 @@ uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averag
|
|||
if (averaging)
|
||||
sample_sum += sample;
|
||||
|
||||
//Check decimation
|
||||
// check decimation
|
||||
if (decimation > 1) {
|
||||
sample_counter++;
|
||||
if (sample_counter < decimation) continue;
|
||||
sample_counter = 0;
|
||||
}
|
||||
|
||||
//Averaging
|
||||
// averaging
|
||||
if (averaging && decimation > 1) {
|
||||
sample = sample_sum / decimation;
|
||||
sample_sum =0;
|
||||
}
|
||||
|
||||
//Store the sample
|
||||
// store the sample
|
||||
sample_total_saved ++;
|
||||
if (bits_per_sample == 8){
|
||||
if (bits_per_sample == 8) {
|
||||
dest[sample_total_saved-1] = sample;
|
||||
data.numbits = sample_total_saved << 3;//Get the return value correct
|
||||
|
||||
// Get the return value correct
|
||||
data.numbits = sample_total_saved << 3;
|
||||
if (sample_total_saved >= bufsize) break;
|
||||
|
||||
} else {
|
||||
|
@ -190,9 +192,8 @@ uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averag
|
|||
if (bits_per_sample > 4) pushBit(&data, sample & 0x08);
|
||||
if (bits_per_sample > 5) pushBit(&data, sample & 0x04);
|
||||
if (bits_per_sample > 6) pushBit(&data, sample & 0x02);
|
||||
//Not needed, 8bps is covered above
|
||||
//if (bits_per_sample > 7) pushBit(&data, sample & 0x01);
|
||||
if ((data.numbits >> 3) +1 >= bufsize) break;
|
||||
|
||||
if ((data.numbits >> 3) + 1 >= bufsize) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -285,10 +286,8 @@ void doT55x7Acquisition(size_t sample_size) {
|
|||
|
||||
while(!BUTTON_PRESS() && !usb_poll_validate_length() && skipCnt < 1000 && (i < bufsize) ) {
|
||||
WDT_HIT();
|
||||
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
|
||||
AT91C_BASE_SSC->SSC_THR = 0x43; //43
|
||||
LED_D_ON();
|
||||
}
|
||||
|
||||
|
||||
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
|
||||
curSample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||
LED_D_OFF();
|
||||
|
@ -352,11 +351,7 @@ void doCotagAcquisition(size_t sample_size) {
|
|||
|
||||
while (!BUTTON_PRESS() && !usb_poll_validate_length() && (i < bufsize) && (noise_counter < (COTAG_T1 << 1)) ) {
|
||||
WDT_HIT();
|
||||
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
|
||||
AT91C_BASE_SSC->SSC_THR = 0x43;
|
||||
LED_D_ON();
|
||||
}
|
||||
|
||||
|
||||
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
|
||||
sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||
LED_D_OFF();
|
||||
|
@ -406,12 +401,8 @@ uint32_t doCotagAcquisitionManchester() {
|
|||
uint16_t noise_counter = 0;
|
||||
|
||||
while (!BUTTON_PRESS() && !usb_poll_validate_length() && (sample_counter < bufsize) && (noise_counter < (COTAG_T1 << 1)) ) {
|
||||
WDT_HIT();
|
||||
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
|
||||
AT91C_BASE_SSC->SSC_THR = 0x43;
|
||||
LED_D_ON();
|
||||
}
|
||||
|
||||
WDT_HIT();
|
||||
|
||||
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
|
||||
sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||
LED_D_OFF();
|
||||
|
|
|
@ -1259,7 +1259,6 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da
|
|||
LED_A_ON();
|
||||
|
||||
if ( firstchunk ) {
|
||||
|
||||
clear_trace();
|
||||
set_tracing(false);
|
||||
|
||||
|
@ -1458,26 +1457,31 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da
|
|||
} // end loop sectors
|
||||
} // end loop keys
|
||||
} // end loop strategy 2
|
||||
OUT:
|
||||
OUT:
|
||||
LEDsoff();
|
||||
|
||||
crypto1_destroy(pcs);
|
||||
|
||||
// All keys found, send to client, or last keychunk from client
|
||||
if (foundkeys == allkeys || lastchunk ) {
|
||||
|
||||
|
||||
uint64_t foo = 0;
|
||||
for (uint8_t m = 0; m < 64; m++) {
|
||||
foo |= ((uint64_t)(found[m] & 1) << m);
|
||||
}
|
||||
|
||||
uint16_t bar = 0;
|
||||
for (uint8_t m = 0; m < 64; ++m)
|
||||
foo |= (found[m] << m);
|
||||
for (uint8_t m=64; m < sizeof(found); ++m)
|
||||
bar |= (found[m] << (m-64));
|
||||
|
||||
uint8_t j = 0;
|
||||
for (uint8_t m=64; m < sizeof(found); m++) {
|
||||
bar |= ((uint16_t)(found[m] & 1) << j++);
|
||||
}
|
||||
|
||||
uint8_t *tmp = BigBuf_malloc(480+10);
|
||||
memcpy(tmp, k_sector, sectorcnt * sizeof(sector_t) );
|
||||
num_to_bytes(foo, 8, tmp+480);
|
||||
tmp[488] = bar & 0xFF;
|
||||
tmp[489] = bar >> 8 & 0xFF;
|
||||
|
||||
cmd_send(CMD_ACK, foundkeys, 0, 0, tmp, 480+10);
|
||||
|
||||
set_tracing(false);
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
*
|
||||
* This is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as published
|
||||
* by the Free Software Foundation.
|
||||
* by the Free Software Foundation, or, at your option, any later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
|
|
|
@ -299,29 +299,29 @@ lualibs/mf_default_keys.lua : default_keys.dic
|
|||
|
||||
clean:
|
||||
$(RM) $(CLEAN)
|
||||
cd ../liblua && make clean
|
||||
cd $(JANSSONLIBPATH) && make clean
|
||||
cd $(MBEDTLSLIBPATH) && make clean
|
||||
cd $(CBORLIBPATH) && make clean
|
||||
cd ../liblua && $(MAKE) clean
|
||||
cd $(JANSSONLIBPATH) && $(MAKE) clean
|
||||
cd $(MBEDTLSLIBPATH) && $(MAKE) clean
|
||||
cd $(CBORLIBPATH) && $(MAKE) clean
|
||||
|
||||
tarbin: $(BINS)
|
||||
$(TAR) $(TARFLAGS) ../proxmark3-$(platform)-bin.tar $(BINS:%=client/%) $(WINBINS:%=client/%)
|
||||
|
||||
lua_build:
|
||||
@echo Compiling liblua, using platform $(LUAPLATFORM)
|
||||
cd ../liblua && make $(LUAPLATFORM)
|
||||
cd ../liblua && $(MAKE) $(LUAPLATFORM)
|
||||
|
||||
jansson_build:
|
||||
@echo Compiling jansson
|
||||
cd $(JANSSONLIBPATH) && make all
|
||||
cd $(JANSSONLIBPATH) && $(MAKE) all
|
||||
|
||||
mbedtls_build:
|
||||
@echo Compiling mbedtls
|
||||
cd $(MBEDTLSLIBPATH) && make all
|
||||
cd $(MBEDTLSLIBPATH) && $(MAKE) all
|
||||
|
||||
cbor_build:
|
||||
@echo Compiling tinycbor
|
||||
cd $(CBORLIBPATH) && make all
|
||||
cd $(CBORLIBPATH) && $(MAKE) all
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
|
|
|
@ -1786,7 +1786,7 @@ int Cmdbin2hex(const char *Cmd) {
|
|||
//Number of digits supplied as argument
|
||||
size_t length = en - bg + 1;
|
||||
size_t bytelen = (length+7) / 8;
|
||||
uint8_t* arr = (uint8_t *) malloc(bytelen);
|
||||
uint8_t* arr = (uint8_t *) calloc(bytelen, sizeof(uint8_t));
|
||||
memset(arr, 0, bytelen);
|
||||
BitstreamOut bout = { arr, 0, 0 };
|
||||
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Proxmark3 RDV40 Flash memory commands
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifdef WITH_FLASH
|
||||
|
||||
#include "cmdflashmem.h"
|
||||
|
||||
#include "mbedtls/rsa.h"
|
||||
|
@ -604,3 +606,5 @@ int CmdHelp(const char *Cmd) {
|
|||
CmdsHelp(CommandTable);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -8,6 +8,8 @@
|
|||
// Proxmark3 RDV40 Flash memory commands
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifdef WITH_FLASH
|
||||
|
||||
#ifndef CMDFLASHMEM_H__
|
||||
#define CMDFLASHMEM_H__
|
||||
|
||||
|
@ -38,4 +40,6 @@ extern int CmdFlashMemLoad(const char* cmd);
|
|||
extern int CmdFlashMemSave(const char* cmd);
|
||||
extern int CmdFlashMemWipe(const char *Cmd);
|
||||
extern int CmdFlashMemInfo(const char *Cmd);
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,6 +1,6 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2010 iZsh <izsh at fail0verflow.com>, Hagen Fritsch
|
||||
// 2011, 2017 Merlok
|
||||
// 2011, 2017 - 2019 Merlok
|
||||
// 2014, Peter Fillmore
|
||||
// 2015, 2016, 2017 Iceman
|
||||
//
|
||||
|
@ -12,6 +12,8 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
#include "cmdhf14a.h"
|
||||
|
||||
bool APDUInFramingEnable = true;
|
||||
|
||||
static int CmdHelp(const char *Cmd);
|
||||
static int waitCmd(uint8_t iLen);
|
||||
|
||||
|
@ -147,6 +149,10 @@ char* getTagInfo(uint8_t uid) {
|
|||
return manufactureMapping[len-1].desc;
|
||||
}
|
||||
|
||||
// iso14a apdu input frame length
|
||||
static uint16_t frameLength = 0;
|
||||
uint16_t atsFSC[] = {16, 24, 32, 40, 48, 64, 96, 128, 256};
|
||||
|
||||
int usage_hf_14a_sim(void) {
|
||||
// PrintAndLogEx(NORMAL, "\n Emulating ISO/IEC 14443 type A tag with 4,7 or 10 byte UID\n");
|
||||
PrintAndLogEx(NORMAL, "\n Emulating ISO/IEC 14443 type A tag with 4,7 byte UID\n");
|
||||
|
@ -486,10 +492,7 @@ int CmdHF14AInfo(const char *Cmd) {
|
|||
(tb1 ? "" : " NOT"),
|
||||
(tc1 ? "" : " NOT"),
|
||||
fsci,
|
||||
fsci < 5 ? (fsci - 2) * 8 :
|
||||
fsci < 8 ? (fsci - 3) * 32 :
|
||||
fsci == 8 ? 256 :
|
||||
-1
|
||||
fsci < sizeof(atsFSC) ? atsFSC[fsci] : -1
|
||||
);
|
||||
}
|
||||
pos = 2;
|
||||
|
@ -836,15 +839,90 @@ int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leav
|
|||
return 0;
|
||||
}
|
||||
|
||||
int CmdExchangeAPDU(uint8_t *datain, int datainlen, bool activateField, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, bool *chaining) {
|
||||
uint16_t cmdc = 0;
|
||||
int SelectCard14443_4(bool disconnect, iso14a_card_select_t *card) {
|
||||
UsbCommand resp;
|
||||
|
||||
*chaining = false;
|
||||
frameLength = 0;
|
||||
|
||||
if (card)
|
||||
memset(card, 0, sizeof(iso14a_card_select_t));
|
||||
|
||||
if (activateField) {
|
||||
cmdc |= ISO14A_CONNECT;
|
||||
DropField();
|
||||
|
||||
// Anticollision + SELECT card
|
||||
UsbCommand ca = {CMD_READER_ISO_14443a, {ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0}};
|
||||
SendCommand(&ca);
|
||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
|
||||
PrintAndLogEx(ERR, "Proxmark connection timeout.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// check result
|
||||
if (resp.arg[0] == 0) {
|
||||
PrintAndLogEx(ERR, "No card in field.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (resp.arg[0] != 1 && resp.arg[0] != 2) {
|
||||
PrintAndLogEx(ERR, "Card not in iso14443-4. res=%d.", resp.arg[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (resp.arg[0] == 2) { // 0: couldn't read, 1: OK, with ATS, 2: OK, no ATS, 3: proprietary Anticollision
|
||||
// get ATS
|
||||
UsbCommand cr = {CMD_READER_ISO_14443a, {ISO14A_RAW | ISO14A_APPEND_CRC | ISO14A_NO_DISCONNECT, 2, 0}};
|
||||
uint8_t rats[] = { 0xE0, 0x80 }; // FSDI=8 (FSD=256), CID=0
|
||||
memcpy(cr.d.asBytes, rats, 2);
|
||||
SendCommand(&cr);
|
||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
|
||||
PrintAndLogEx(ERR, "Proxmark connection timeout.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (resp.arg[0] <= 0) { // ats_len
|
||||
PrintAndLogEx(ERR, "Can't get ATS.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// get frame length from ATS in data field
|
||||
if (resp.arg[0] > 1) {
|
||||
uint8_t fsci = resp.d.asBytes[1] & 0x0f;
|
||||
if (fsci < sizeof(atsFSC))
|
||||
frameLength = atsFSC[fsci];
|
||||
}
|
||||
} else {
|
||||
// get frame length from ATS in card data structure
|
||||
iso14a_card_select_t *vcard = (iso14a_card_select_t *) resp.d.asBytes;
|
||||
if (vcard->ats_len > 1) {
|
||||
uint8_t fsci = vcard->ats[1] & 0x0f;
|
||||
if (fsci < sizeof(atsFSC))
|
||||
frameLength = atsFSC[fsci];
|
||||
}
|
||||
|
||||
if (card)
|
||||
memcpy(card, vcard, sizeof(iso14a_card_select_t));
|
||||
}
|
||||
|
||||
if (disconnect)
|
||||
DropField();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdExchangeAPDU(bool chainingin, uint8_t *datain, int datainlen, bool activateField, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, bool *chainingout) {
|
||||
*chainingout = false;
|
||||
|
||||
if (activateField) {
|
||||
// select with no disconnect and set frameLength
|
||||
int selres = SelectCard14443_4(false, NULL);
|
||||
if (selres)
|
||||
return selres;
|
||||
}
|
||||
|
||||
uint16_t cmdc = 0;
|
||||
if (chainingin)
|
||||
cmdc = ISO14A_SEND_CHAINING;
|
||||
|
||||
// "Command APDU" length should be 5+255+1, but javacard's APDU buffer might be smaller - 133 bytes
|
||||
// https://stackoverflow.com/questions/32994936/safe-max-java-card-apdu-data-command-and-respond-size
|
||||
// here length USB_CMD_DATA_SIZE=512
|
||||
|
@ -856,18 +934,6 @@ int CmdExchangeAPDU(uint8_t *datain, int datainlen, bool activateField, uint8_t
|
|||
uint8_t *recv;
|
||||
UsbCommand resp;
|
||||
|
||||
if (activateField) {
|
||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
|
||||
PrintAndLogEx(ERR, "APDU: Proxmark connection timeout.");
|
||||
return 1;
|
||||
}
|
||||
if (resp.arg[0] != 1) {
|
||||
PrintAndLogEx(ERR, "APDU: Proxmark error %d.", resp.arg[0]);
|
||||
DropField();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
|
||||
recv = resp.d.asBytes;
|
||||
int iLen = resp.arg[0];
|
||||
|
@ -883,13 +949,20 @@ int CmdExchangeAPDU(uint8_t *datain, int datainlen, bool activateField, uint8_t
|
|||
return 2;
|
||||
}
|
||||
|
||||
// I-block ACK
|
||||
if ((res & 0xf2) == 0xa2) {
|
||||
*dataoutlen = 0;
|
||||
*chainingout = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(!iLen) {
|
||||
PrintAndLogEx(ERR, "APDU: No APDU response.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// check apdu length
|
||||
if (iLen < 4 && iLen >= 0) {
|
||||
if (iLen < 2 && iLen >= 0) {
|
||||
PrintAndLogEx(ERR, "APDU: Small APDU response. Len=%d", iLen);
|
||||
return 2;
|
||||
}
|
||||
|
@ -904,7 +977,7 @@ int CmdExchangeAPDU(uint8_t *datain, int datainlen, bool activateField, uint8_t
|
|||
|
||||
// chaining
|
||||
if ((res & 0x10) != 0) {
|
||||
*chaining = true;
|
||||
*chainingout = true;
|
||||
}
|
||||
|
||||
// CRC Check
|
||||
|
@ -923,12 +996,57 @@ int CmdExchangeAPDU(uint8_t *datain, int datainlen, bool activateField, uint8_t
|
|||
int ExchangeAPDU14a(uint8_t *datain, int datainlen, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen) {
|
||||
*dataoutlen = 0;
|
||||
bool chaining = false;
|
||||
|
||||
int res = CmdExchangeAPDU(datain, datainlen, activateField, dataout, maxdataoutlen, dataoutlen, &chaining);
|
||||
int res;
|
||||
|
||||
// 3 byte here - 1b framing header, 2b crc16
|
||||
if (APDUInFramingEnable &&
|
||||
( (frameLength && (datainlen > frameLength - 3)) || (datainlen > USB_CMD_DATA_SIZE - 3)) ) {
|
||||
int clen = 0;
|
||||
|
||||
bool vActivateField = activateField;
|
||||
|
||||
do {
|
||||
int vlen = MIN(frameLength - 3, datainlen - clen);
|
||||
bool chainBlockNotLast = ((clen + vlen) < datainlen);
|
||||
|
||||
*dataoutlen = 0;
|
||||
res = CmdExchangeAPDU(chainBlockNotLast, &datain[clen], vlen, vActivateField, dataout, maxdataoutlen, dataoutlen, &chaining);
|
||||
if (res) {
|
||||
if (!leaveSignalON)
|
||||
DropField();
|
||||
|
||||
return 200;
|
||||
}
|
||||
|
||||
// check R-block ACK
|
||||
if ((*dataoutlen == 0) && (*dataoutlen != 0 || chaining != chainBlockNotLast)) {
|
||||
if (!leaveSignalON)
|
||||
DropField();
|
||||
|
||||
return 201;
|
||||
}
|
||||
|
||||
clen += vlen;
|
||||
vActivateField = false;
|
||||
if (*dataoutlen) {
|
||||
if (clen != datainlen)
|
||||
PrintAndLogEx(WARNING, "APDU: I-block/R-block sequence error. Data len=%d, Sent=%d, Last packet len=%d", datainlen, clen, *dataoutlen);
|
||||
break;
|
||||
}
|
||||
} while (clen < datainlen);
|
||||
} else {
|
||||
res = CmdExchangeAPDU(false, datain, datainlen, activateField, dataout, maxdataoutlen, dataoutlen, &chaining);
|
||||
if (res) {
|
||||
if (!leaveSignalON)
|
||||
DropField();
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
while (chaining) {
|
||||
// I-block with chaining
|
||||
res = CmdExchangeAPDU(NULL, 0, false, &dataout[*dataoutlen], maxdataoutlen, dataoutlen, &chaining);
|
||||
res = CmdExchangeAPDU(false, NULL, 0, false, &dataout[*dataoutlen], maxdataoutlen, dataoutlen, &chaining);
|
||||
|
||||
if (res) {
|
||||
if (!leaveSignalON)
|
||||
|
@ -1205,16 +1323,48 @@ int CmdHF14AAntiFuzz(const char *cmd) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int CmdHF14AChaining(const char *cmd) {
|
||||
|
||||
CLIParserInit("hf 14a chaining",
|
||||
"Enable/Disable ISO14443a input chaining. Maximum input length goes from ATS.",
|
||||
"Usage:\n"
|
||||
"\thf 14a chaining disable -> disable chaining\n"
|
||||
"\thf 14a chaining -> show chaining enable/disable state\n");
|
||||
|
||||
void* argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_str0(NULL, NULL, "<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[] = {
|
||||
{"help", CmdHelp, 1, "This help"},
|
||||
{"list", CmdHF14AList, 0, "[Deprecated] List ISO 14443-a history"},
|
||||
{"info", CmdHF14AInfo, 0, "Tag information"},
|
||||
{"reader", CmdHF14AReader, 0, "Act like an ISO14443-a reader"},
|
||||
{"reader", CmdHF14AReader, 0, "Act like an ISO14443-a reader"},
|
||||
{"cuids", CmdHF14ACUIDs, 0, "<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"},
|
||||
{"apdu", CmdHF14AAPDU, 0, "Send ISO 14443-4 APDU to tag"},
|
||||
{"raw", CmdHF14ACmdRaw, 0, "Send raw hex data to tag"},
|
||||
{"chaining", CmdHF14AChaining, 0, "Control ISO 14443-4 input chaining"},
|
||||
{"raw", CmdHF14ACmdRaw, 0, "Send raw hex data to tag"},
|
||||
{"antifuzz", CmdHF14AAntiFuzz, 0, "Fuzzing the anticollision phase. Warning! Readers may react strange"},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
|
|
@ -519,21 +519,21 @@ int CmdHF15Info(const char *Cmd) {
|
|||
SendCommand(&c);
|
||||
|
||||
if ( !WaitForResponseTimeout(CMD_ACK, &resp, 2000) ) {
|
||||
PrintAndLogEx(NORMAL, "iso15693 card select failed");
|
||||
PrintAndLogEx(WARNING, "iso15693 card select failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint32_t status = resp.arg[0];
|
||||
|
||||
if ( status < 2 ) {
|
||||
PrintAndLogEx(NORMAL, "iso15693 card doesn't answer to systeminfo command");
|
||||
PrintAndLogEx(WARNING, "iso15693 card doesn't answer to systeminfo command");
|
||||
return 1;
|
||||
}
|
||||
|
||||
recv = resp.d.asBytes;
|
||||
|
||||
if ( recv[0] & ISO15_RES_ERROR ) {
|
||||
PrintAndLogEx(NORMAL, "iso15693 card returned error %i: %s", recv[0], TagErrorStr(recv[0]));
|
||||
PrintAndLogEx(WARNING, "iso15693 card returned error %i: %s", recv[0], TagErrorStr(recv[0]));
|
||||
return 3;
|
||||
}
|
||||
|
||||
|
@ -575,8 +575,8 @@ int CmdHF15Info(const char *Cmd) {
|
|||
// Record Activity without enabeling carrier
|
||||
//helptext
|
||||
int CmdHF15Record(const char *Cmd) {
|
||||
char cmdp = param_getchar(Cmd, 0);
|
||||
if (cmdp == 'h' || cmdp == 'H') return usage_15_record();
|
||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||
if (cmdp == 'h') return usage_15_record();
|
||||
|
||||
UsbCommand c = {CMD_RECORD_RAW_ADC_SAMPLES_ISO_15693, {0,0,0}};
|
||||
clearCommandBuffer();
|
||||
|
@ -598,8 +598,8 @@ int HF15Reader(const char *Cmd, bool verbose) {
|
|||
}
|
||||
|
||||
int CmdHF15Reader(const char *Cmd) {
|
||||
char cmdp = param_getchar(Cmd, 0);
|
||||
if (cmdp == 'h' || cmdp == 'H') return usage_15_reader();
|
||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||
if (cmdp == 'h') return usage_15_reader();
|
||||
|
||||
HF15Reader(Cmd, true);
|
||||
return 0;
|
||||
|
@ -608,16 +608,16 @@ int CmdHF15Reader(const char *Cmd) {
|
|||
// Simulation is still not working very good
|
||||
// helptext
|
||||
int CmdHF15Sim(const char *Cmd) {
|
||||
char cmdp = param_getchar(Cmd, 0);
|
||||
if (strlen(Cmd) < 1 || cmdp == 'h' || cmdp == 'H') return usage_15_sim();
|
||||
char cmdp =tolower(param_getchar(Cmd, 0));
|
||||
if (strlen(Cmd) < 1 || cmdp == 'h') return usage_15_sim();
|
||||
|
||||
uint8_t uid[8] = {0,0,0,0,0,0,0,0};
|
||||
if (param_gethex(Cmd, 0, uid, 16)) {
|
||||
PrintAndLogEx(NORMAL, "UID must include 16 HEX symbols");
|
||||
PrintAndLogEx(WARNING, "UID must include 16 HEX symbols");
|
||||
return 0;
|
||||
}
|
||||
|
||||
PrintAndLogEx(NORMAL, "Starting simulating UID %s", sprint_hex(uid, sizeof(uid)) );
|
||||
PrintAndLogEx(SUCCESS, "Starting simulating UID %s", sprint_hex(uid, sizeof(uid)) );
|
||||
|
||||
UsbCommand c = {CMD_SIMTAG_ISO_15693, {0, 0, 0}};
|
||||
memcpy(c.d.asBytes, uid, 8);
|
||||
|
@ -630,10 +630,10 @@ int CmdHF15Sim(const char *Cmd) {
|
|||
// (There is no standard way of reading the AFI, allthough some tags support this)
|
||||
// helptext
|
||||
int CmdHF15Afi(const char *Cmd) {
|
||||
char cmdp = param_getchar(Cmd, 0);
|
||||
if (cmdp == 'h' || cmdp == 'H') return usage_15_findafi();
|
||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||
if (cmdp == 'h') return usage_15_findafi();
|
||||
|
||||
PrintAndLogEx(NORMAL, "press pm3-button to cancel");
|
||||
PrintAndLogEx(SUCCESS, "press pm3-button to cancel");
|
||||
|
||||
UsbCommand c = {CMD_ISO_15693_FIND_AFI, {strtol(Cmd, NULL, 0), 0, 0}};
|
||||
clearCommandBuffer();
|
||||
|
@ -689,7 +689,7 @@ int CmdHF15Dump(const char*Cmd) {
|
|||
}
|
||||
// detect blocksize from card :)
|
||||
|
||||
PrintAndLogEx(NORMAL, "Reading memory from tag UID %s", sprintUID(NULL, uid));
|
||||
PrintAndLogEx(NORMAL, "Reading memory from tag UID " _YELLOW_(%s), sprintUID(NULL, uid));
|
||||
|
||||
int blocknum = 0;
|
||||
uint8_t *recv = NULL;
|
||||
|
@ -764,7 +764,7 @@ int CmdHF15Dump(const char*Cmd) {
|
|||
}
|
||||
|
||||
int CmdHF15Restore(const char*Cmd) {
|
||||
FILE *file;
|
||||
FILE *f;
|
||||
|
||||
uint8_t uid[8]={0x00};
|
||||
char filename[FILE_PATH_SIZE] = {0x00};
|
||||
|
@ -774,10 +774,10 @@ int CmdHF15Restore(const char*Cmd) {
|
|||
char newCmdPrefix[255] = {0x00}, tmpCmd[255] = {0x00};
|
||||
char param[FILE_PATH_SIZE]="";
|
||||
char hex[255]="";
|
||||
uint8_t retries = 3, tried = 0;
|
||||
uint8_t retries = 3, tried = 0, i = 0;
|
||||
int retval=0;
|
||||
size_t bytes_read;
|
||||
uint8_t i=0;
|
||||
|
||||
while(param_getchar(Cmd, cmdp) != 0x00) {
|
||||
switch(tolower(param_getchar(Cmd, cmdp))) {
|
||||
case '-':
|
||||
|
@ -785,7 +785,8 @@ int CmdHF15Restore(const char*Cmd) {
|
|||
switch(param[1])
|
||||
{
|
||||
case '2':
|
||||
case 'o': strncpy(newCmdPrefix, " ",sizeof(newCmdPrefix)-1);
|
||||
case 'o':
|
||||
strncpy(newCmdPrefix, " ", sizeof(newCmdPrefix)-1);
|
||||
strncat(newCmdPrefix, param, sizeof(newCmdPrefix)-1);
|
||||
break;
|
||||
default:
|
||||
|
@ -815,18 +816,18 @@ int CmdHF15Restore(const char*Cmd) {
|
|||
default:
|
||||
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
||||
return usage_15_restore();
|
||||
break;
|
||||
}
|
||||
cmdp++;
|
||||
}
|
||||
|
||||
PrintAndLogEx(INFO,"Blocksize: %u",blocksize);
|
||||
if(filename[0]=='\0')
|
||||
{
|
||||
|
||||
if ( !strlen(filename)) {
|
||||
PrintAndLogEx(WARNING,"Please provide a filename");
|
||||
return 1;
|
||||
return usage_15_restore();
|
||||
}
|
||||
|
||||
if ((file = fopen(filename,"rb")) == NULL) {
|
||||
if ((f = fopen(filename, "rb")) == NULL) {
|
||||
PrintAndLogEx(WARNING, "Could not find file %s", filename);
|
||||
return 2;
|
||||
}
|
||||
|
@ -835,40 +836,43 @@ int CmdHF15Restore(const char*Cmd) {
|
|||
PrintAndLogEx(WARNING, "No tag found");
|
||||
return 3;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
tried=0;
|
||||
hex[0]=0x00;
|
||||
tmpCmd[0]=0x00;
|
||||
tried = 0;
|
||||
hex[0] = 0x00;
|
||||
tmpCmd[0] = 0x00;
|
||||
|
||||
bytes_read = fread( buff, 1, blocksize, file );
|
||||
bytes_read = fread( buff, 1, blocksize, f );
|
||||
if ( bytes_read == 0) {
|
||||
PrintAndLogEx(SUCCESS, "File reading done (%s).", filename);
|
||||
fclose(file);
|
||||
PrintAndLogEx(SUCCESS, "File reading done `%s`", filename);
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
else if ( bytes_read != blocksize) {
|
||||
} else if ( bytes_read != blocksize) {
|
||||
PrintAndLogEx(WARNING, "File reading error (%s), %u bytes read instead of %u bytes.", filename, bytes_read, blocksize);
|
||||
fclose(file);
|
||||
fclose(f);
|
||||
return 2;
|
||||
}
|
||||
for(int j=0;j<blocksize;j++)
|
||||
snprintf(hex+j*2,3,"%02X", (unsigned char)buff[j]);
|
||||
for(int j=0;j<sizeof(uid)/sizeof(uid[0]);j++)
|
||||
|
||||
for(int j=0; j < blocksize; 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]);
|
||||
|
||||
//TODO: Addressed mode currently not work
|
||||
//snprintf(tmpCmd, sizeof(tmpCmd), "%s %s %d %s", newCmdPrefix, buff, i, hex);
|
||||
snprintf(tmpCmd, sizeof(tmpCmd), "%s u %d %s", newCmdPrefix, i, hex);
|
||||
PrintAndLogEx(DEBUG, "Command to be sent: %s", tmpCmd);
|
||||
snprintf(tmpCmd, sizeof(tmpCmd), "%s u %u %s", newCmdPrefix, i, hex);
|
||||
PrintAndLogEx(DEBUG, "Command to be sent| %s", tmpCmd);
|
||||
|
||||
for(tried=0;tried<retries;tried++)
|
||||
if(!(retval=CmdHF15Write(tmpCmd)))
|
||||
for(tried=0; tried < retries; tried++)
|
||||
if(!(retval = CmdHF15Write(tmpCmd)))
|
||||
break;
|
||||
if(tried >= retries)
|
||||
return retval;
|
||||
|
||||
i++;
|
||||
}
|
||||
fclose(file);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
int CmdHF15List(const char *Cmd) {
|
||||
|
@ -1241,7 +1245,7 @@ int CmdHF15Write(const char *Cmd) {
|
|||
AddCrc(req, reqlen);
|
||||
c.arg[0] = reqlen+2;
|
||||
|
||||
PrintAndLogEx(NORMAL, "iso15693 writing to page %02d (0x&02X) | data ", pagenum, pagenum);
|
||||
PrintAndLogEx(NORMAL, "iso15693 writing to page %02d (0x%02X) | data ", pagenum, pagenum);
|
||||
|
||||
clearCommandBuffer();
|
||||
SendCommand(&c);
|
||||
|
|
|
@ -43,7 +43,7 @@ int CmdHFEPACollectPACENonces(const char *Cmd)
|
|||
PrintAndLogEx(FAILED, "Error in step %d, Return code: %d",resp.arg[0],(int)resp.arg[1]);
|
||||
} else {
|
||||
size_t nonce_length = resp.arg[1];
|
||||
char *nonce = (char *) malloc(2 * nonce_length + 1);
|
||||
char *nonce = (char *) calloc(2 * nonce_length + 1, sizeof(uint8_t));
|
||||
for(int j = 0; j < nonce_length; j++) {
|
||||
sprintf(nonce + (2 * j), "%02X", resp.d.asBytes[j]);
|
||||
}
|
||||
|
|
|
@ -404,7 +404,7 @@ int CmdHFiClassSim(const char *Cmd) {
|
|||
break;
|
||||
|
||||
size_t datalen = NUM_CSNS * 24;
|
||||
void* dump = malloc(datalen);
|
||||
void* dump = calloc(datalen, sizeof(uint8_t));
|
||||
if ( !dump ) {
|
||||
PrintAndLogEx(WARNING, "Failed to allocate memory");
|
||||
return 2;
|
||||
|
@ -456,7 +456,7 @@ int CmdHFiClassSim(const char *Cmd) {
|
|||
break;
|
||||
|
||||
size_t datalen = NUM_CSNS * 24;
|
||||
void* dump = malloc(datalen);
|
||||
void* dump = calloc(datalen, sizeof(uint8_t));
|
||||
if ( !dump ) {
|
||||
PrintAndLogEx(WARNING, "Failed to allocate memory");
|
||||
return 2;
|
||||
|
@ -2463,7 +2463,7 @@ static void shave(uint8_t *data, uint8_t len){
|
|||
data[i] &= 0xFE;
|
||||
}
|
||||
static void generate_rev(uint8_t *data, uint8_t len) {
|
||||
uint8_t *key = calloc(len,1);
|
||||
uint8_t *key = calloc(len, sizeof(uint8_t));
|
||||
PrintAndLogEx(SUCCESS, "input permuted key | %s \n", sprint_hex(data, len));
|
||||
permute_rev(data, len, key);
|
||||
PrintAndLogEx(SUCCESS, " unpermuted key | %s \n", sprint_hex(key, len));
|
||||
|
@ -2472,8 +2472,8 @@ static void generate_rev(uint8_t *data, uint8_t len) {
|
|||
free(key);
|
||||
}
|
||||
static void generate(uint8_t *data, uint8_t len) {
|
||||
uint8_t *key = calloc(len,1);
|
||||
uint8_t *pkey = calloc(len,1);
|
||||
uint8_t *key = calloc(len, sizeof(uint8_t));
|
||||
uint8_t *pkey = calloc(len, sizeof(uint8_t));
|
||||
PrintAndLogEx(SUCCESS, " input key | %s \n", sprint_hex(data, len));
|
||||
permute(data, len, pkey);
|
||||
PrintAndLogEx(SUCCESS, "permuted key | %s \n", sprint_hex(pkey, len));
|
||||
|
|
|
@ -180,15 +180,14 @@ int CmdLegicInfo(const char *Cmd) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
PrintAndLogEx(NORMAL, "Reading tag memory %d b...", card.cardsize);
|
||||
PrintAndLogEx(SUCCESS, "Reading tag memory %d b...", card.cardsize);
|
||||
|
||||
// allocate receiver buffer
|
||||
uint8_t *data = malloc(card.cardsize);
|
||||
uint8_t *data = calloc(card.cardsize, sizeof(uint8_t));
|
||||
if (!data) {
|
||||
PrintAndLogEx(WARNING, "Cannot allocate memory");
|
||||
return 2;
|
||||
}
|
||||
memset(data, 0, card.cardsize);
|
||||
|
||||
int status = legic_read_mem(0, card.cardsize, 0x55, data, &datalen);
|
||||
if ( status > 0 ) {
|
||||
|
@ -480,15 +479,20 @@ int CmdLegicRdmem(const char *Cmd) {
|
|||
uint16_t datalen = 0;
|
||||
sscanf(Cmd, "%x %x %x", &offset, &len, &iv);
|
||||
|
||||
PrintAndLogEx(NORMAL, "Reading %d bytes, from offset %d", len, offset);
|
||||
// sanity checks
|
||||
if ( len + offset >= MAX_LENGTH ) {
|
||||
PrintAndLogEx(WARNING, "Out-of-bounds, Cardsize = %d, [offset+len = %d ]", MAX_LENGTH, len + offset);
|
||||
return -1;
|
||||
}
|
||||
|
||||
PrintAndLogEx(SUCCESS, "Reading %d bytes, from offset %d", len, offset);
|
||||
|
||||
// allocate receiver buffer
|
||||
uint8_t *data = malloc(len);
|
||||
uint8_t *data = calloc(len, sizeof(uint8_t));
|
||||
if ( !data ){
|
||||
PrintAndLogEx(WARNING, "Cannot allocate memory");
|
||||
return 2;
|
||||
return -2;
|
||||
}
|
||||
memset(data, 0, len);
|
||||
|
||||
int status = legic_read_mem(offset, len, iv, data, &datalen);
|
||||
if ( status == 0 ) {
|
||||
|
@ -540,9 +544,9 @@ int CmdLegicRfWrite(const char *Cmd) {
|
|||
}
|
||||
|
||||
// limit number of bytes to write. This is not a 'restore' command.
|
||||
if ( (len>>1) > 100 ){
|
||||
PrintAndLogEx(NORMAL, "Max bound on 100bytes to write a one time.");
|
||||
PrintAndLogEx(NORMAL, "Use the 'hf legic restore' command if you want to write the whole tag at once");
|
||||
if ( (len >> 1) > 100 ){
|
||||
PrintAndLogEx(WARNING, "Max bound on 100bytes to write a one time.");
|
||||
PrintAndLogEx(WARNING, "Use the 'hf legic restore' command if you want to write the whole tag at once");
|
||||
errors = true;
|
||||
}
|
||||
|
||||
|
@ -551,7 +555,7 @@ int CmdLegicRfWrite(const char *Cmd) {
|
|||
if (data)
|
||||
free(data);
|
||||
|
||||
data = malloc(len >> 1);
|
||||
data = calloc(len >> 1, sizeof(uint8_t));
|
||||
if ( data == NULL ) {
|
||||
PrintAndLogEx(WARNING, "Can't allocate memory. exiting");
|
||||
errors = true;
|
||||
|
@ -598,12 +602,12 @@ int CmdLegicRfWrite(const char *Cmd) {
|
|||
// OUT-OF-BOUNDS checks
|
||||
// UID 4+1 bytes can't be written to.
|
||||
if ( offset < 5 ) {
|
||||
PrintAndLogEx(NORMAL, "Out-of-bounds, bytes 0-1-2-3-4 can't be written to. Offset = %d", offset);
|
||||
PrintAndLogEx(WARNING, "Out-of-bounds, bytes 0-1-2-3-4 can't be written to. Offset = %d", offset);
|
||||
return -2;
|
||||
}
|
||||
|
||||
if ( len + offset >= card.cardsize ) {
|
||||
PrintAndLogEx(NORMAL, "Out-of-bounds, Cardsize = %d, [offset+len = %d ]", card.cardsize, len + offset);
|
||||
PrintAndLogEx(WARNING, "Out-of-bounds, Cardsize = %d, [offset+len = %d ]", card.cardsize, len + offset);
|
||||
return -2;
|
||||
}
|
||||
|
||||
|
@ -622,7 +626,7 @@ int CmdLegicRfWrite(const char *Cmd) {
|
|||
|
||||
legic_chk_iv(&IV);
|
||||
|
||||
PrintAndLogEx(NORMAL, "Writing to tag");
|
||||
PrintAndLogEx(SUCCESS, "Writing to tag");
|
||||
|
||||
UsbCommand c = {CMD_WRITER_LEGIC_RF, {offset, len, IV}};
|
||||
memcpy(c.d.asBytes, data, len);
|
||||
|
@ -630,10 +634,18 @@ int CmdLegicRfWrite(const char *Cmd) {
|
|||
clearCommandBuffer();
|
||||
SendCommand(&c);
|
||||
|
||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
|
||||
PrintAndLogEx(WARNING, "command execution time out");
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t timeout = 0;
|
||||
while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
|
||||
++timeout;
|
||||
printf("."); fflush(stdout);
|
||||
if (timeout > 7) {
|
||||
PrintAndLogEx(WARNING, "\ncommand execution time out");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
PrintAndLogEx(NORMAL, "\n");
|
||||
|
||||
uint8_t isOK = resp.arg[0] & 0xFF;
|
||||
if ( !isOK ) {
|
||||
PrintAndLogEx(WARNING, "Failed writing tag");
|
||||
|
@ -673,7 +685,7 @@ int CmdLegicCalcCrc(const char *Cmd){
|
|||
// it's possible for user to accidentally enter "b" parameter
|
||||
// more than once - we have to clean previous malloc
|
||||
if (data) free(data);
|
||||
data = malloc(len >> 1);
|
||||
data = calloc(len >> 1, sizeof(uint8_t) );
|
||||
if ( data == NULL ) {
|
||||
PrintAndLogEx(WARNING, "Can't allocate memory. exiting");
|
||||
errors = true;
|
||||
|
@ -714,10 +726,10 @@ int CmdLegicCalcCrc(const char *Cmd){
|
|||
switch (type){
|
||||
case 16:
|
||||
init_table(CRC_LEGIC);
|
||||
PrintAndLogEx(NORMAL, "Legic crc16: %X", crc16_legic(data, len, uidcrc));
|
||||
PrintAndLogEx(SUCCESS, "Legic crc16: %X", crc16_legic(data, len, uidcrc));
|
||||
break;
|
||||
default:
|
||||
PrintAndLogEx(NORMAL, "Legic crc8: %X", CRC8Legic(data, len) );
|
||||
PrintAndLogEx(SUCCESS, "Legic crc8: %X", CRC8Legic(data, len) );
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -733,11 +745,18 @@ int legic_read_mem(uint32_t offset, uint32_t len, uint32_t iv, uint8_t *out, uin
|
|||
clearCommandBuffer();
|
||||
SendCommand(&c);
|
||||
UsbCommand resp;
|
||||
if ( !WaitForResponseTimeout(CMD_ACK, &resp, 3000) ) {
|
||||
PrintAndLogEx(WARNING, "command execution time out");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
uint8_t timeout = 0;
|
||||
while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
|
||||
++timeout;
|
||||
printf("."); fflush(stdout);
|
||||
if (timeout > 7) {
|
||||
PrintAndLogEx(WARNING, "\ncommand execution time out");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
PrintAndLogEx(NORMAL, "\n");
|
||||
|
||||
uint8_t isOK = resp.arg[0] & 0xFF;
|
||||
*outlen = resp.arg[1];
|
||||
if ( !isOK ) {
|
||||
|
@ -762,13 +781,13 @@ int legic_print_type(uint32_t tagtype, uint8_t spaces){
|
|||
char *spacer = spc + (10-spaces);
|
||||
|
||||
if ( tagtype == 22 )
|
||||
PrintAndLogEx(NORMAL, "%sTYPE : MIM%d card (outdated)", spacer, tagtype);
|
||||
PrintAndLogEx(SUCCESS, "%sTYPE : MIM%d card (outdated)", spacer, tagtype);
|
||||
else if ( tagtype == 256 )
|
||||
PrintAndLogEx(NORMAL, "%sTYPE : MIM%d card (234 bytes)", spacer, tagtype);
|
||||
PrintAndLogEx(SUCCESS, "%sTYPE : MIM%d card (234 bytes)", spacer, tagtype);
|
||||
else if ( tagtype == 1024 )
|
||||
PrintAndLogEx(NORMAL, "%sTYPE : MIM%d card (1002 bytes)", spacer, tagtype);
|
||||
PrintAndLogEx(SUCCESS, "%sTYPE : MIM%d card (1002 bytes)", spacer, tagtype);
|
||||
else
|
||||
PrintAndLogEx(NORMAL, "%sTYPE : Unknown %06x", spacer, tagtype);
|
||||
PrintAndLogEx(INFO, "%sTYPE : Unknown %06x", spacer, tagtype);
|
||||
return 0;
|
||||
}
|
||||
int legic_get_type(legic_card_select_t *card){
|
||||
|
@ -792,12 +811,12 @@ int legic_get_type(legic_card_select_t *card){
|
|||
void legic_chk_iv(uint32_t *iv){
|
||||
if ( (*iv & 0x7F) != *iv ){
|
||||
*iv &= 0x7F;
|
||||
PrintAndLogEx(NORMAL, "Truncating IV to 7bits, %u", *iv);
|
||||
PrintAndLogEx(INFO, "Truncating IV to 7bits, %u", *iv);
|
||||
}
|
||||
// IV must be odd
|
||||
if ( (*iv & 1) == 0 ){
|
||||
*iv |= 0x01;
|
||||
PrintAndLogEx(NORMAL, "LSB of IV must be SET %u", *iv);
|
||||
PrintAndLogEx(INFO, "LSB of IV must be SET %u", *iv);
|
||||
}
|
||||
}
|
||||
void legic_seteml(uint8_t *src, uint32_t offset, uint32_t numofbytes) {
|
||||
|
@ -828,11 +847,11 @@ int HFLegicReader(const char *Cmd, bool verbose) {
|
|||
if ( verbose ) PrintAndLogEx(WARNING, "command execution time out");
|
||||
return 1;
|
||||
case 3:
|
||||
if ( verbose ) PrintAndLogEx(NORMAL, "legic card select failed");
|
||||
if ( verbose ) PrintAndLogEx(WARNING, "legic card select failed");
|
||||
return 2;
|
||||
default: break;
|
||||
}
|
||||
PrintAndLogEx(NORMAL, " UID : %s", sprint_hex(card.uid, sizeof(card.uid)));
|
||||
PrintAndLogEx(SUCCESS, " UID : %s", sprint_hex(card.uid, sizeof(card.uid)));
|
||||
legic_print_type(card.cardsize, 0);
|
||||
return 0;
|
||||
}
|
||||
|
@ -882,16 +901,23 @@ int CmdLegicDump(const char *Cmd){
|
|||
dumplen = card.cardsize;
|
||||
|
||||
legic_print_type(dumplen, 0);
|
||||
PrintAndLogEx(NORMAL, "Reading tag memory %d b...", dumplen);
|
||||
PrintAndLogEx(SUCCESS, "Reading tag memory %d b...", dumplen);
|
||||
|
||||
UsbCommand c = {CMD_READER_LEGIC_RF, {0x00, dumplen, 0x55}};
|
||||
clearCommandBuffer();
|
||||
SendCommand(&c);
|
||||
UsbCommand resp;
|
||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 3000)) {
|
||||
PrintAndLogEx(NORMAL, "Command execute time-out");
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t timeout = 0;
|
||||
while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
|
||||
++timeout;
|
||||
printf("."); fflush(stdout);
|
||||
if (timeout > 7) {
|
||||
PrintAndLogEx(WARNING, "\ncommand execution time out");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
PrintAndLogEx(NORMAL, "\n");
|
||||
|
||||
uint8_t isOK = resp.arg[0] & 0xFF;
|
||||
if ( !isOK ) {
|
||||
|
@ -900,12 +926,11 @@ int CmdLegicDump(const char *Cmd){
|
|||
}
|
||||
|
||||
uint16_t readlen = resp.arg[1];
|
||||
uint8_t *data = malloc(readlen);
|
||||
uint8_t *data = calloc(readlen, sizeof(uint8_t));
|
||||
if (!data) {
|
||||
PrintAndLogEx(WARNING, "Fail, cannot allocate memory");
|
||||
return 3;
|
||||
}
|
||||
memset(data, 0, readlen);
|
||||
|
||||
if ( readlen != dumplen )
|
||||
PrintAndLogEx(WARNING, "Fail, only managed to read 0x%02X bytes of 0x%02X", readlen, dumplen);
|
||||
|
@ -923,7 +948,7 @@ int CmdLegicDump(const char *Cmd){
|
|||
else
|
||||
sprintf(fnameptr + fileNlen,".bin");
|
||||
|
||||
f = fopen(filename,"wb");
|
||||
f = fopen(filename, "wb");
|
||||
if (!f) {
|
||||
PrintAndLogEx(WARNING, "Could not create file name %s", filename);
|
||||
if (data)
|
||||
|
@ -934,7 +959,7 @@ int CmdLegicDump(const char *Cmd){
|
|||
fflush(f);
|
||||
fclose(f);
|
||||
free(data);
|
||||
PrintAndLogEx(NORMAL, "Wrote %d bytes to %s", readlen, filename);
|
||||
PrintAndLogEx(SUCCESS, "Wrote %d bytes to %s", readlen, filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -982,12 +1007,11 @@ int CmdLegicRestore(const char *Cmd){
|
|||
numofbytes = card.cardsize;
|
||||
|
||||
// set up buffer
|
||||
uint8_t *data = malloc(numofbytes);
|
||||
uint8_t *data = calloc(numofbytes, sizeof(uint8_t) );
|
||||
if (!data) {
|
||||
PrintAndLogEx(WARNING, "Fail, cannot allocate memory");
|
||||
return 2;
|
||||
}
|
||||
memset(data, 0, numofbytes);
|
||||
|
||||
legic_print_type(numofbytes, 0);
|
||||
|
||||
|
@ -997,7 +1021,7 @@ int CmdLegicRestore(const char *Cmd){
|
|||
|
||||
f = fopen(filename,"rb");
|
||||
if (!f) {
|
||||
PrintAndLogEx(NORMAL, "File %s not found or locked", filename);
|
||||
PrintAndLogEx(WARNING, "File %s not found or locked", filename);
|
||||
return 3;
|
||||
}
|
||||
|
||||
|
@ -1018,12 +1042,12 @@ int CmdLegicRestore(const char *Cmd){
|
|||
fclose(f);
|
||||
|
||||
if ( bytes_read == 0){
|
||||
PrintAndLogEx(NORMAL, "File reading error");
|
||||
PrintAndLogEx(WARNING, "File reading error");
|
||||
free(data);
|
||||
return 2;
|
||||
}
|
||||
|
||||
PrintAndLogEx(NORMAL, "Restoring to card");
|
||||
PrintAndLogEx(SUCCESS, "Restoring to card");
|
||||
|
||||
// transfer to device
|
||||
size_t len = 0;
|
||||
|
@ -1038,22 +1062,29 @@ int CmdLegicRestore(const char *Cmd){
|
|||
clearCommandBuffer();
|
||||
SendCommand(&c);
|
||||
|
||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 4000)) {
|
||||
PrintAndLogEx(WARNING, "command execution time out");
|
||||
free(data);
|
||||
return 1;
|
||||
}
|
||||
uint8_t timeout = 0;
|
||||
while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
|
||||
++timeout;
|
||||
printf("."); fflush(stdout);
|
||||
if (timeout > 7) {
|
||||
PrintAndLogEx(WARNING, "\ncommand execution time out");
|
||||
free(data);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
PrintAndLogEx(NORMAL, "\n");
|
||||
|
||||
uint8_t isOK = resp.arg[0] & 0xFF;
|
||||
if ( !isOK ) {
|
||||
PrintAndLogEx(WARNING, "Failed writing tag [msg = %u]", resp.arg[1] & 0xFF);
|
||||
free(data);
|
||||
return 1;
|
||||
}
|
||||
PrintAndLogEx(NORMAL, "Wrote chunk [offset %d | len %d | total %d", i, len, i+len);
|
||||
PrintAndLogEx(SUCCESS, "Wrote chunk [offset %d | len %d | total %d", i, len, i+len);
|
||||
}
|
||||
|
||||
free(data);
|
||||
PrintAndLogEx(NORMAL, "\nWrote %d bytes to card from file %s", numofbytes, filename);
|
||||
PrintAndLogEx(SUCCESS, "\nWrote %d bytes to card from file %s", numofbytes, filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1077,12 +1108,11 @@ int CmdLegicELoad(const char *Cmd) {
|
|||
}
|
||||
|
||||
// set up buffer
|
||||
uint8_t *data = malloc(numofbytes);
|
||||
uint8_t *data = calloc(numofbytes, sizeof(uint8_t));
|
||||
if (!data) {
|
||||
PrintAndLogEx(WARNING, "Fail, cannot allocate memory");
|
||||
return 3;
|
||||
}
|
||||
memset(data, 0, numofbytes);
|
||||
|
||||
// set up file
|
||||
len = param_getstr(Cmd, nameParamNo, filename, FILE_PATH_SIZE);
|
||||
|
@ -1094,7 +1124,7 @@ int CmdLegicELoad(const char *Cmd) {
|
|||
// open file
|
||||
f = fopen(filename,"rb");
|
||||
if (!f) {
|
||||
PrintAndLogEx(NORMAL, "File %s not found or locked", filename);
|
||||
PrintAndLogEx(WARNING, "File %s not found or locked", filename);
|
||||
free(data);
|
||||
return 1;
|
||||
}
|
||||
|
@ -1102,7 +1132,7 @@ int CmdLegicELoad(const char *Cmd) {
|
|||
// load file
|
||||
size_t bytes_read = fread(data, 1, numofbytes, f);
|
||||
if ( bytes_read == 0){
|
||||
PrintAndLogEx(NORMAL, "File reading error");
|
||||
PrintAndLogEx(WARNING, "File reading error");
|
||||
free(data);
|
||||
fclose(f);
|
||||
f = NULL;
|
||||
|
@ -1115,7 +1145,7 @@ int CmdLegicELoad(const char *Cmd) {
|
|||
legic_seteml(data, 0, numofbytes);
|
||||
|
||||
free(data);
|
||||
PrintAndLogEx(NORMAL, "\nLoaded %d bytes from file: %s to emulator memory", numofbytes, filename);
|
||||
PrintAndLogEx(SUCCESS, "\nLoaded %d bytes from file: %s to emulator memory", numofbytes, filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1146,15 +1176,14 @@ int CmdLegicESave(const char *Cmd) {
|
|||
fileNlen = FILE_PATH_SIZE - 5;
|
||||
|
||||
// set up buffer
|
||||
uint8_t *data = malloc(numofbytes);
|
||||
uint8_t *data = calloc(numofbytes, sizeof(uint8_t));
|
||||
if (!data) {
|
||||
PrintAndLogEx(WARNING, "Fail, cannot allocate memory");
|
||||
return 3;
|
||||
}
|
||||
memset(data, 0, numofbytes);
|
||||
|
||||
// download emulator memory
|
||||
PrintAndLogEx(NORMAL, "Reading emulator memory...");
|
||||
PrintAndLogEx(SUCCESS, "Reading emulator memory...");
|
||||
if (!GetFromDevice( BIG_BUF_EML, data, numofbytes, 0, NULL, 2500, false)) {
|
||||
PrintAndLogEx(WARNING, "Fail, transfer from device time-out");
|
||||
free(data);
|
||||
|
@ -1185,16 +1214,15 @@ int CmdLegicWipe(const char *Cmd){
|
|||
}
|
||||
|
||||
// set up buffer
|
||||
uint8_t *data = malloc(card.cardsize);
|
||||
uint8_t *data = calloc(card.cardsize, sizeof(uint8_t));
|
||||
if (!data) {
|
||||
PrintAndLogEx(WARNING, "Fail, cannot allocate memory");
|
||||
return 2;
|
||||
}
|
||||
memset(data, 0, card.cardsize);
|
||||
|
||||
legic_print_type(card.cardsize, 0);
|
||||
|
||||
PrintAndLogEx(NORMAL, "Erasing");
|
||||
PrintAndLogEx(SUCCESS, "Erasing");
|
||||
|
||||
// transfer to device
|
||||
size_t len = 0;
|
||||
|
@ -1210,11 +1238,18 @@ int CmdLegicWipe(const char *Cmd){
|
|||
clearCommandBuffer();
|
||||
SendCommand(&c);
|
||||
|
||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 4000)) {
|
||||
PrintAndLogEx(WARNING, "command execution time out");
|
||||
free(data);
|
||||
return 3;
|
||||
}
|
||||
uint8_t timeout = 0;
|
||||
while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
|
||||
++timeout;
|
||||
printf("."); fflush(stdout);
|
||||
if (timeout > 7) {
|
||||
PrintAndLogEx(WARNING, "\ncommand execution time out");
|
||||
free(data);
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
PrintAndLogEx(NORMAL, "\n");
|
||||
|
||||
uint8_t isOK = resp.arg[0] & 0xFF;
|
||||
if ( !isOK ) {
|
||||
PrintAndLogEx(WARNING, "Failed writing tag [msg = %u]", resp.arg[1] & 0xFF);
|
||||
|
@ -1222,7 +1257,7 @@ int CmdLegicWipe(const char *Cmd){
|
|||
return 4;
|
||||
}
|
||||
}
|
||||
PrintAndLogEx(NORMAL, "ok\n");
|
||||
PrintAndLogEx(SUCCESS, "ok\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1236,7 +1271,7 @@ static command_t CommandTable[] = {
|
|||
{"reader", CmdLegicReader, 1, "LEGIC Prime Reader UID and tag info"},
|
||||
{"info", CmdLegicInfo, 0, "Display deobfuscated and decoded LEGIC Prime tag data"},
|
||||
{"dump", CmdLegicDump, 0, "Dump LEGIC Prime tag to binary file"},
|
||||
{"restore", CmdLegicRestore, 0, "Restore a dump onto a LEGIC Prime tag"},
|
||||
{"restore", CmdLegicRestore, 0, "Restore a dump file onto a LEGIC Prime tag"},
|
||||
{"rdmem", CmdLegicRdmem, 0, "Read bytes from a LEGIC Prime tag"},
|
||||
{"sim", CmdLegicRfSim, 0, "Start tag simulator"},
|
||||
{"write", CmdLegicRfWrite, 0, "Write data to a LEGIC Prime tag"},
|
||||
|
|
|
@ -357,7 +357,7 @@ void annotateIso7816(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize){
|
|||
case ISO7816_EXTERNAL_AUTHENTICATION :snprintf(exp, size, "EXTERNAL AUTH");break;
|
||||
case ISO7816_GET_CHALLENGE :snprintf(exp, size, "GET CHALLENGE");break;
|
||||
case ISO7816_MANAGE_CHANNEL :snprintf(exp, size, "MANAGE CHANNEL");break;
|
||||
case ISO7816_GETSTATUS :snprintf(exp, size, "GET RESPONSE");break;
|
||||
case ISO7816_GET_RESPONSE :snprintf(exp, size, "GET RESPONSE");break;
|
||||
default :snprintf(exp,size,"?"); break;
|
||||
}
|
||||
}
|
||||
|
|
279
client/cmdhfmf.c
279
client/cmdhfmf.c
|
@ -11,11 +11,16 @@
|
|||
#include "cmdhfmf.h"
|
||||
#include "mifare4.h"
|
||||
|
||||
#define MIFARE_4K_MAXBLOCK 255
|
||||
#define MIFARE_4K_MAXBLOCK 256
|
||||
#define MIFARE_2K_MAXBLOCK 128
|
||||
#define MIFARE_1K_MAXBLOCK 64
|
||||
#define MIFARE_MINI_MAXBLOCK 20
|
||||
|
||||
#define MIFARE_MINI_MAXSECTOR 5
|
||||
#define MIFARE_1K_MAXSECTOR 16
|
||||
#define MIFARE_2K_MAXSECTOR 32
|
||||
#define MIFARE_4K_MAXSECTOR 40
|
||||
|
||||
static int CmdHelp(const char *Cmd);
|
||||
|
||||
int usage_hf14_ice(void){
|
||||
|
@ -415,7 +420,7 @@ int GetHFMF14AUID(uint8_t *uid, int *uidlen) {
|
|||
char * GenerateFilename(const char *prefix, const char *suffix){
|
||||
uint8_t uid[10] = {0,0,0,0,0,0,0,0,0,0};
|
||||
int uidlen=0;
|
||||
char * fptr = malloc (sizeof (char) * (strlen(prefix) + strlen(suffix)) + sizeof(uid)*2 + 1);
|
||||
char * fptr = calloc (sizeof (char) * (strlen(prefix) + strlen(suffix)) + sizeof(uid)*2 + 1, sizeof(uint8_t));
|
||||
|
||||
GetHFMF14AUID(uid, &uidlen);
|
||||
if (!uidlen) {
|
||||
|
@ -591,7 +596,7 @@ int CmdHF14AMfRdSc(const char *Cmd) {
|
|||
}
|
||||
|
||||
sectorNo = param_get8(Cmd, 0);
|
||||
if (sectorNo > 39) {
|
||||
if (sectorNo > MIFARE_4K_MAXSECTOR ) {
|
||||
PrintAndLogEx(NORMAL, "Sector number must be less than 40");
|
||||
return 1;
|
||||
}
|
||||
|
@ -645,7 +650,7 @@ int CmdHF14AMfRdSc(const char *Cmd) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
uint8_t NumOfBlocks(char card){
|
||||
uint16_t NumOfBlocks(char card){
|
||||
switch(card){
|
||||
case '0' : return MIFARE_MINI_MAXBLOCK;
|
||||
case '1' : return MIFARE_1K_MAXBLOCK;
|
||||
|
@ -656,11 +661,11 @@ uint8_t NumOfBlocks(char card){
|
|||
}
|
||||
uint8_t NumOfSectors(char card){
|
||||
switch(card){
|
||||
case '0' : return 5;
|
||||
case '1' : return 16;
|
||||
case '2' : return 32;
|
||||
case '4' : return 40;
|
||||
default : return 16;
|
||||
case '0' : return MIFARE_MINI_MAXSECTOR;
|
||||
case '1' : return MIFARE_1K_MAXSECTOR;
|
||||
case '2' : return MIFARE_2K_MAXSECTOR;
|
||||
case '4' : return MIFARE_4K_MAXSECTOR;
|
||||
default : return MIFARE_1K_MAXSECTOR;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -729,7 +734,7 @@ int CmdHF14AMfDump(const char *Cmd) {
|
|||
}
|
||||
|
||||
if ((fin = fopen(keyFilename, "rb")) == NULL) {
|
||||
PrintAndLogEx(WARNING, "Could not find file %s", keyFilename);
|
||||
PrintAndLogEx(WARNING, "Could not find file " _YELLOW_(%s), keyFilename);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -738,7 +743,7 @@ int CmdHF14AMfDump(const char *Cmd) {
|
|||
for (sectorNo=0; sectorNo<numSectors; sectorNo++) {
|
||||
bytes_read = fread( keyA[sectorNo], 1, 6, fin );
|
||||
if ( bytes_read != 6) {
|
||||
PrintAndLogEx(NORMAL, "File reading error.");
|
||||
PrintAndLogEx(WARNING, "File reading error.");
|
||||
fclose(fin);
|
||||
return 2;
|
||||
}
|
||||
|
@ -748,7 +753,7 @@ int CmdHF14AMfDump(const char *Cmd) {
|
|||
for (sectorNo=0; sectorNo<numSectors; sectorNo++) {
|
||||
bytes_read = fread( keyB[sectorNo], 1, 6, fin );
|
||||
if ( bytes_read != 6) {
|
||||
PrintAndLogEx(NORMAL, "File reading error.");
|
||||
PrintAndLogEx(WARNING, "File reading error.");
|
||||
fclose(fin);
|
||||
return 2;
|
||||
}
|
||||
|
@ -874,13 +879,13 @@ int CmdHF14AMfDump(const char *Cmd) {
|
|||
}
|
||||
|
||||
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;
|
||||
}
|
||||
uint16_t numblocks = FirstBlockOfSector(numSectors - 1) + NumBlocksPerSector(numSectors - 1);
|
||||
fwrite(carddata, 1, 16*numblocks, 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;
|
||||
}
|
||||
|
@ -940,7 +945,7 @@ int CmdHF14AMfRestore(const char *Cmd) {
|
|||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -948,7 +953,7 @@ int CmdHF14AMfRestore(const char *Cmd) {
|
|||
for (sectorNo = 0; sectorNo < numSectors; sectorNo++) {
|
||||
bytes_read = fread( keyA[sectorNo], 1, 6, fkeys );
|
||||
if ( bytes_read != 6 ) {
|
||||
PrintAndLogEx(NORMAL, "File reading error (%s).", keyFilename);
|
||||
PrintAndLogEx(WARNING, "File reading error " _YELLOW_(%s), keyFilename);
|
||||
fclose(fkeys);
|
||||
return 2;
|
||||
}
|
||||
|
@ -957,7 +962,7 @@ int CmdHF14AMfRestore(const char *Cmd) {
|
|||
for (sectorNo = 0; sectorNo < numSectors; sectorNo++) {
|
||||
bytes_read = fread( keyB[sectorNo], 1, 6, fkeys );
|
||||
if ( bytes_read != 6 ) {
|
||||
PrintAndLogEx(NORMAL, "File reading error (%s).", keyFilename);
|
||||
PrintAndLogEx(WARNING, "File reading error " _YELLOW_(%s), keyFilename);
|
||||
fclose(fkeys);
|
||||
return 2;
|
||||
}
|
||||
|
@ -974,10 +979,10 @@ int CmdHF14AMfRestore(const char *Cmd) {
|
|||
}
|
||||
|
||||
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;
|
||||
}
|
||||
PrintAndLogEx(NORMAL, "Restoring %s to card", dataFilename);
|
||||
PrintAndLogEx(INFO, "Restoring " _YELLOW_(%s)" to card", dataFilename);
|
||||
|
||||
for (sectorNo = 0; sectorNo < numSectors; sectorNo++) {
|
||||
for (blockNo = 0; blockNo < NumBlocksPerSector(sectorNo); blockNo++) {
|
||||
|
@ -985,7 +990,7 @@ int CmdHF14AMfRestore(const char *Cmd) {
|
|||
memcpy(c.d.asBytes, key, 6);
|
||||
bytes_read = fread(bldata, 1, 16, fdump);
|
||||
if ( bytes_read != 16) {
|
||||
PrintAndLogEx(NORMAL, "File reading error (%s).", dataFilename);
|
||||
PrintAndLogEx(WARNING, "File reading error " _YELLOW_(%s), dataFilename);
|
||||
fclose(fdump);
|
||||
fdump = NULL;
|
||||
return 2;
|
||||
|
@ -1015,9 +1020,9 @@ int CmdHF14AMfRestore(const char *Cmd) {
|
|||
UsbCommand resp;
|
||||
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
|
||||
uint8_t isOK = resp.arg[0] & 0xff;
|
||||
PrintAndLogEx(NORMAL, "isOk:%02x", isOK);
|
||||
PrintAndLogEx(SUCCESS, "isOk:%02x", isOK);
|
||||
} else {
|
||||
PrintAndLogEx(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?
|
||||
PrintAndLogEx(SUCCESS, "trying to read key B...");
|
||||
PrintAndLogEx(INFO, "trying to read key B...");
|
||||
for (i = 0; i < SectorsCnt; i++) {
|
||||
// KEY A but not KEY B
|
||||
if ( e_sector[i].foundKey[0] && !e_sector[i].foundKey[1] ) {
|
||||
|
@ -1230,8 +1235,8 @@ int CmdHF14AMfNested(const char *Cmd) {
|
|||
if (e_sector[i].foundKey[1])
|
||||
num_to_bytes(e_sector[i].Key[1], 6, &keyBlock[10]);
|
||||
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
|
||||
|
@ -1241,12 +1246,12 @@ int CmdHF14AMfNested(const char *Cmd) {
|
|||
return 1;
|
||||
|
||||
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);
|
||||
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++) {
|
||||
if (e_sector[i].foundKey[0]){
|
||||
num_to_bytes(e_sector[i].Key[0], 6, tempkey);
|
||||
|
@ -1314,14 +1319,14 @@ int CmdHF14AMfNestedHard(const char *Cmd) {
|
|||
default:
|
||||
if (param_getchar(Cmd, cmdp) == 0x00)
|
||||
{
|
||||
PrintAndLogEx(NORMAL, "Block number is missing");
|
||||
PrintAndLogEx(WARNING, "Block number is missing");
|
||||
return 1;
|
||||
|
||||
}
|
||||
blockNo = param_get8(Cmd, cmdp);
|
||||
ctmp = tolower(param_getchar(Cmd, cmdp+1));
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -1330,13 +1335,13 @@ int CmdHF14AMfNestedHard(const char *Cmd) {
|
|||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (param_getchar(Cmd, cmdp+3) == 0x00)
|
||||
{
|
||||
PrintAndLogEx(NORMAL, "Target block number is missing");
|
||||
PrintAndLogEx(WARNING, "Target block number is missing");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1344,7 +1349,7 @@ int CmdHF14AMfNestedHard(const char *Cmd) {
|
|||
|
||||
ctmp = tolower(param_getchar(Cmd, cmdp+4));
|
||||
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;
|
||||
}
|
||||
if (ctmp != 'a') {
|
||||
|
@ -1402,7 +1407,7 @@ int CmdHF14AMfNestedHard(const char *Cmd) {
|
|||
SetSIMDInstr(SIMD_NONE);
|
||||
break;
|
||||
default:
|
||||
PrintAndLog("Unknown SIMD type. %c", ctmp);
|
||||
PrintAndLogEx(WARNING, "Unknown SIMD type. %c", ctmp);
|
||||
return 1;
|
||||
}
|
||||
cmdp += 2;
|
||||
|
@ -1420,7 +1425,7 @@ int CmdHF14AMfNestedHard(const char *Cmd) {
|
|||
// check if we can authenticate to sector
|
||||
int res = mfCheckKeys(blockNo, keyType, true, 1, key, &key64);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -1497,11 +1502,11 @@ int CmdHF14AMfChk_fast(const char *Cmd) {
|
|||
|
||||
// sectors
|
||||
switch(ctmp) {
|
||||
case '0': sectorsCnt = 5; break;
|
||||
case '1': sectorsCnt = 16; break;
|
||||
case '2': sectorsCnt = 32; break;
|
||||
case '4': sectorsCnt = 40; break;
|
||||
default: sectorsCnt = 16;
|
||||
case '0': sectorsCnt = MIFARE_MINI_MAXSECTOR; break;
|
||||
case '1': sectorsCnt = MIFARE_1K_MAXSECTOR; break;
|
||||
case '2': sectorsCnt = MIFARE_2K_MAXSECTOR; break;
|
||||
case '4': sectorsCnt = MIFARE_4K_MAXSECTOR; break;
|
||||
default: sectorsCnt = MIFARE_1K_MAXSECTOR;
|
||||
}
|
||||
|
||||
for (i = 1; param_getchar(Cmd, i); i++) {
|
||||
|
@ -1542,7 +1547,7 @@ int CmdHF14AMfChk_fast(const char *Cmd) {
|
|||
|
||||
f = fopen( filename, "r");
|
||||
if ( !f ){
|
||||
PrintAndLogEx(FAILED, "File: %s: not found or locked.", filename);
|
||||
PrintAndLogEx(FAILED, "File: " _YELLOW_(%s) ": not found or locked.", filename);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1556,7 +1561,7 @@ int CmdHF14AMfChk_fast(const char *Cmd) {
|
|||
if( buf[0]=='#' ) continue; //The line start with # is comment, skip
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -1578,7 +1583,7 @@ int CmdHF14AMfChk_fast(const char *Cmd) {
|
|||
memset(buf, 0, sizeof(buf));
|
||||
}
|
||||
fclose(f);
|
||||
PrintAndLogEx(SUCCESS, "Loaded %2d keys from %s", keycnt, filename);
|
||||
PrintAndLogEx(SUCCESS, "Loaded %2d keys from " _YELLOW_(%s), keycnt, filename);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1617,7 +1622,7 @@ int CmdHF14AMfChk_fast(const char *Cmd) {
|
|||
|
||||
if (ukbhit()) {
|
||||
int gc = getchar(); (void)gc;
|
||||
PrintAndLogEx(NORMAL, "\naborted via keyboard!\n");
|
||||
PrintAndLogEx(WARNING, "\naborted via keyboard!\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -1644,47 +1649,63 @@ out:
|
|||
t1 = msclock() - t1;
|
||||
PrintAndLogEx(SUCCESS, "Time in checkkeys (fast): %.1fs\n", (float)(t1/1000.0));
|
||||
|
||||
printKeyTable( sectorsCnt, e_sector );
|
||||
|
||||
if (transferToEml) {
|
||||
uint8_t block[16] = {0x00};
|
||||
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(NORMAL, "Found keys have been transferred to the emulator memory");
|
||||
// check..
|
||||
uint8_t found_keys = 0;
|
||||
for (uint8_t i = 0; i < sectorsCnt; ++i) {
|
||||
|
||||
if ( e_sector[i].foundKey[0] )
|
||||
found_keys++;
|
||||
|
||||
if ( e_sector[i].foundKey[1] )
|
||||
found_keys++;
|
||||
}
|
||||
|
||||
if (createDumpFile) {
|
||||
fptr = GenerateFilename("hf-mf-", "-key.bin");
|
||||
if (fptr == NULL)
|
||||
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);
|
||||
if ( found_keys == 0 ) {
|
||||
PrintAndLogEx(WARNING, "No keys found");
|
||||
} else {
|
||||
|
||||
for (i=0; i<sectorsCnt; i++) {
|
||||
num_to_bytes(e_sector[i].Key[0], 6, tempkey);
|
||||
fwrite (tempkey, 1, 6, fkeys);
|
||||
}
|
||||
printKeyTable( sectorsCnt, e_sector );
|
||||
|
||||
for (i=0; i<sectorsCnt; i++) {
|
||||
num_to_bytes(e_sector[i].Key[1], 6, tempkey);
|
||||
fwrite (tempkey, 1, 6, fkeys );
|
||||
if (transferToEml) {
|
||||
uint8_t block[16] = {0x00};
|
||||
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);
|
||||
PrintAndLogEx(NORMAL, "Found keys have been dumped to %s --> 0xffffffffffff has been inserted for unknown keys.", fptr);
|
||||
FILE *fkeys = fopen(fptr, "wb");
|
||||
if (fkeys == NULL) {
|
||||
PrintAndLogEx(WARNING, "Could not create file " _YELLOW_(%s), fptr);
|
||||
free(keyBlock);
|
||||
free(e_sector);
|
||||
return 1;
|
||||
}
|
||||
PrintAndLogEx(SUCCESS, "Printing keys to binary file " _YELLOW_(%s)"...", fptr);
|
||||
|
||||
for (i=0; i<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);
|
||||
|
@ -1695,8 +1716,8 @@ out:
|
|||
|
||||
int CmdHF14AMfChk(const char *Cmd) {
|
||||
|
||||
char ctmp = param_getchar(Cmd, 0);
|
||||
if (strlen(Cmd) < 3 || ctmp == 'h' || ctmp == 'H') return usage_hf14_chk();
|
||||
char ctmp = tolower(param_getchar(Cmd, 0));
|
||||
if (strlen(Cmd) < 3 || ctmp == 'h') return usage_hf14_chk();
|
||||
|
||||
FILE * f;
|
||||
char filename[FILE_PATH_SIZE]={0};
|
||||
|
@ -1729,23 +1750,21 @@ int CmdHF14AMfChk(const char *Cmd) {
|
|||
blockNo = param_get8(Cmd, 0);
|
||||
}
|
||||
|
||||
ctmp = param_getchar(Cmd, 1);
|
||||
ctmp = tolower(param_getchar(Cmd, 1));
|
||||
clen = param_getlength(Cmd, 1);
|
||||
if (clen == 1) {
|
||||
switch (ctmp) {
|
||||
case 'a':
|
||||
case 'A':
|
||||
keyType = 0;
|
||||
break;
|
||||
case 'b':
|
||||
case 'B':
|
||||
keyType = 1;
|
||||
break;
|
||||
case '?':
|
||||
keyType = 2;
|
||||
break;
|
||||
default:
|
||||
PrintAndLogEx(NORMAL, "Key type must be A , B or ?");
|
||||
PrintAndLogEx(FAILED, "Key type must be A , B or ?");
|
||||
free(keyBlock);
|
||||
return 1;
|
||||
};
|
||||
|
@ -1753,7 +1772,7 @@ int CmdHF14AMfChk(const char *Cmd) {
|
|||
|
||||
for (i = 2; param_getchar(Cmd, i); i++) {
|
||||
|
||||
ctmp = param_getchar(Cmd, i);
|
||||
ctmp = tolower(param_getchar(Cmd, i));
|
||||
clen = param_getlength(Cmd, i);
|
||||
|
||||
if (clen == 12) {
|
||||
|
@ -1775,8 +1794,8 @@ int CmdHF14AMfChk(const char *Cmd) {
|
|||
PrintAndLogEx(NORMAL, "[%2d] key %s", keycnt, sprint_hex( (keyBlock + 6*keycnt), 6 ) );;
|
||||
keycnt++;
|
||||
} else if ( clen == 1 ) {
|
||||
if (ctmp == 't' || ctmp == 'T') { transferToEml = 1; continue; }
|
||||
if (ctmp == 'd' || ctmp == 'D') { createDumpFile = 1; continue; }
|
||||
if (ctmp == 't' ) { transferToEml = 1; continue; }
|
||||
if (ctmp == 'd' ) { createDumpFile = 1; continue; }
|
||||
} else {
|
||||
// May be a dic file
|
||||
if ( param_getstr(Cmd, i, filename, sizeof(filename)) >= FILE_PATH_SIZE ) {
|
||||
|
@ -1786,7 +1805,7 @@ int CmdHF14AMfChk(const char *Cmd) {
|
|||
|
||||
f = fopen( filename , "r");
|
||||
if ( !f ) {
|
||||
PrintAndLogEx(FAILED, "File: %s: not found or locked.", filename);
|
||||
PrintAndLogEx(FAILED, "File: " _YELLOW_(%s)": not found or locked.", filename);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1801,7 +1820,7 @@ int CmdHF14AMfChk(const char *Cmd) {
|
|||
|
||||
// codesmell, only checks first char?
|
||||
if (!isxdigit(buf[0])){
|
||||
PrintAndLogEx(FAILED, "File content error. '%s' must include 12 HEX symbols",buf);
|
||||
PrintAndLogEx(FAILED, "File content error. '" _YELLOW_(%s)"' must include 12 HEX symbols",buf);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1824,12 +1843,12 @@ int CmdHF14AMfChk(const char *Cmd) {
|
|||
memset(buf, 0, sizeof(buf));
|
||||
}
|
||||
fclose(f);
|
||||
PrintAndLogEx(SUCCESS, "Loaded %2d keys from %s", keycnt, filename);
|
||||
PrintAndLogEx(SUCCESS, "Loaded %2d keys from " _YELLOW_(%s), keycnt, filename);
|
||||
}
|
||||
}
|
||||
|
||||
if (keycnt == 0) {
|
||||
PrintAndLogEx(NORMAL, "No key specified, trying default keys");
|
||||
PrintAndLogEx(INFO, "No key specified, trying default keys");
|
||||
for (;keycnt < MIFARE_DEFAULTKEYS_SIZE; keycnt++)
|
||||
PrintAndLogEx(NORMAL, "[%2d] %02x%02x%02x%02x%02x%02x", keycnt,
|
||||
(keyBlock + 6*keycnt)[0],(keyBlock + 6*keycnt)[1], (keyBlock + 6*keycnt)[2],
|
||||
|
@ -1873,7 +1892,7 @@ int CmdHF14AMfChk(const char *Cmd) {
|
|||
printf("."); fflush(stdout);
|
||||
if (ukbhit()) {
|
||||
int gc = getchar(); (void)gc;
|
||||
PrintAndLogEx(NORMAL, "\naborted via keyboard!\n");
|
||||
PrintAndLogEx(INFO, "\naborted via keyboard!\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -1892,12 +1911,12 @@ int CmdHF14AMfChk(const char *Cmd) {
|
|||
}
|
||||
}
|
||||
t1 = msclock() - t1;
|
||||
PrintAndLogEx(NORMAL, "\nTime in checkkeys: %.0f seconds\n", (float)t1/1000.0);
|
||||
PrintAndLogEx(SUCCESS, "\nTime in checkkeys: %.0f seconds\n", (float)t1/1000.0);
|
||||
|
||||
|
||||
// 20160116 If Sector A is found, but not Sector B, try just reading it of the tag?
|
||||
if ( keyType != 1 ) {
|
||||
PrintAndLogEx(NORMAL, "testing to read key B...");
|
||||
PrintAndLogEx(INFO, "testing to read key B...");
|
||||
for (i = 0; i < SectorsCnt; i++) {
|
||||
// KEY A but not KEY B
|
||||
if ( e_sector[i].foundKey[0] && !e_sector[i].foundKey[1] ) {
|
||||
|
@ -1943,7 +1962,7 @@ out:
|
|||
num_to_bytes(e_sector[i].Key[1], 6, block+10);
|
||||
mfEmlSetMem(block, FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1, 1);
|
||||
}
|
||||
PrintAndLogEx(NORMAL, "Found keys have been transferred to the emulator memory");
|
||||
PrintAndLogEx(SUCCESS, "Found keys have been transferred to the emulator memory");
|
||||
}
|
||||
|
||||
if (createDumpFile) {
|
||||
|
@ -1953,12 +1972,12 @@ out:
|
|||
|
||||
FILE *fkeys = fopen(fptr, "wb");
|
||||
if (fkeys == NULL) {
|
||||
PrintAndLogEx(WARNING, "Could not create file %s", fptr);
|
||||
PrintAndLogEx(WARNING, "Could not create file " _YELLOW_(%s), fptr);
|
||||
free(keyBlock);
|
||||
free(e_sector);
|
||||
return 1;
|
||||
}
|
||||
PrintAndLogEx(NORMAL, "Printing keys to binary file %s...", fptr);
|
||||
PrintAndLogEx(INFO, "Printing keys to binary file " _YELLOW_(%s)"...", fptr);
|
||||
|
||||
for( i=0; i<SectorsCnt; i++) {
|
||||
num_to_bytes(e_sector[i].Key[0], 6, tempkey);
|
||||
|
@ -1969,7 +1988,7 @@ out:
|
|||
fwrite ( tempkey, 1, 6, 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);
|
||||
|
@ -2018,7 +2037,7 @@ void readerAttack(nonces_t data, bool setEmulatorMem, bool verbose) {
|
|||
uint8_t sector = data.sector;
|
||||
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"
|
||||
, sector
|
||||
, 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[1], 6, memBlock+10);
|
||||
//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
|
||||
, sprint_hex( memBlock, sizeof(memBlock))
|
||||
);
|
||||
|
@ -2108,7 +2127,7 @@ int CmdHF14AMf1kSim(const char *Cmd) {
|
|||
UsbCommand resp;
|
||||
|
||||
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() ){
|
||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500) ) continue;
|
||||
|
@ -2144,8 +2163,8 @@ int CmdHF14AMfSniff(const char *Cmd){
|
|||
|
||||
memset(uid, 0x00, sizeof(uid));
|
||||
|
||||
char ctmp = param_getchar(Cmd, 0);
|
||||
if ( ctmp == 'h' || ctmp == 'H' ) return usage_hf14_sniff();
|
||||
char ctmp = tolower(param_getchar(Cmd, 0));
|
||||
if ( ctmp == 'h') return usage_hf14_sniff();
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
ctmp = tolower(param_getchar(Cmd, i));
|
||||
|
@ -2172,7 +2191,7 @@ int CmdHF14AMfSniff(const char *Cmd){
|
|||
printf("."); fflush(stdout);
|
||||
if (ukbhit()) {
|
||||
int gc = getchar(); (void)gc;
|
||||
PrintAndLogEx(NORMAL, "\n[!] aborted via keyboard!\n");
|
||||
PrintAndLogEx(INFO, "\naborted via keyboard!\n");
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -2195,7 +2214,7 @@ int CmdHF14AMfSniff(const char *Cmd){
|
|||
if (traceLen > bufsize || buf == NULL) {
|
||||
uint8_t *p;
|
||||
if (buf == NULL) // not yet allocated
|
||||
p = malloc(traceLen);
|
||||
p = calloc(traceLen, sizeof(uint8_t));
|
||||
else // need more memory
|
||||
p = realloc(buf, traceLen);
|
||||
|
||||
|
@ -2412,14 +2431,14 @@ int CmdHF14AMfELoad(const char *Cmd) {
|
|||
return usage_hf14_eload();
|
||||
|
||||
switch (c) {
|
||||
case '0' : numBlocks = 5*4; break;
|
||||
case '0' : numBlocks = MIFARE_MINI_MAXBLOCK; break;
|
||||
case '1' :
|
||||
case '\0': numBlocks = 16*4; break;
|
||||
case '2' : numBlocks = 32*4; break;
|
||||
case '4' : numBlocks = 256; break;
|
||||
case '\0': numBlocks = MIFARE_1K_MAXBLOCK; break;
|
||||
case '2' : numBlocks = MIFARE_2K_MAXBLOCK; break;
|
||||
case '4' : numBlocks = MIFARE_4K_MAXBLOCK; break;
|
||||
case 'u' : numBlocks = 255; blockWidth = 4; break;
|
||||
default: {
|
||||
numBlocks = 16*4;
|
||||
numBlocks = MIFARE_1K_MAXBLOCK;
|
||||
nameParamNo = 0;
|
||||
}
|
||||
}
|
||||
|
@ -2475,7 +2494,7 @@ int CmdHF14AMfELoad(const char *Cmd) {
|
|||
return 4;
|
||||
}
|
||||
}
|
||||
PrintAndLogEx(SUCCESS, "Loaded %d blocks from file: %s", blockNum, filename);
|
||||
PrintAndLogEx(SUCCESS, "Loaded %d blocks from file: " _YELLOW_(%s), blockNum, filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2496,14 +2515,14 @@ int CmdHF14AMfESave(const char *Cmd) {
|
|||
blocks = NumOfBlocks(c);
|
||||
bytes = blocks * MFBLOCK_SIZE;
|
||||
|
||||
dump = calloc(sizeof(uint8_t), bytes);
|
||||
dump = calloc(bytes, sizeof(uint8_t));
|
||||
if (!dump) {
|
||||
PrintAndLogEx(WARNING, "Fail, cannot allocate memory");
|
||||
return 1;
|
||||
}
|
||||
memset(dump, 0, bytes);
|
||||
|
||||
PrintAndLogEx(INFO, "dowingloading from emulator memory");
|
||||
PrintAndLogEx(INFO, "downloading from emulator memory");
|
||||
if (!GetFromDevice( BIG_BUF_EML, dump, bytes, 0, NULL, 2500, false)) {
|
||||
PrintAndLogEx(WARNING, "Fail, transfer from device time-out");
|
||||
free(dump);
|
||||
|
@ -2761,7 +2780,7 @@ int CmdHF14AMfCLoad(const char *Cmd) {
|
|||
blockNum++;
|
||||
|
||||
// magic card type - mifare 1K
|
||||
if (blockNum >= 16 * 4) break;
|
||||
if (blockNum >= MIFARE_1K_MAXBLOCK ) break;
|
||||
}
|
||||
PrintAndLogEx(NORMAL, "\n");
|
||||
|
||||
|
@ -2783,8 +2802,8 @@ int CmdHF14AMfCGetBlk(const char *Cmd) {
|
|||
int res;
|
||||
memset(data, 0x00, sizeof(data));
|
||||
|
||||
char ctmp = param_getchar(Cmd, 0);
|
||||
if (strlen(Cmd) < 1 || ctmp == 'h' || ctmp == 'H') return usage_hf14_cgetblk();
|
||||
char ctmp = tolower(param_getchar(Cmd, 0));
|
||||
if (strlen(Cmd) < 1 || ctmp == 'h') return usage_hf14_cgetblk();
|
||||
|
||||
blockNo = param_get8(Cmd, 0);
|
||||
|
||||
|
@ -2819,8 +2838,8 @@ int CmdHF14AMfCGetSc(const char *Cmd) {
|
|||
uint8_t sector = 0;
|
||||
int i, res, flags;
|
||||
|
||||
char ctmp = param_getchar(Cmd, 0);
|
||||
if (strlen(Cmd) < 1 || ctmp == 'h' || ctmp == 'H') return usage_hf14_cgetsc();
|
||||
char ctmp = tolower(param_getchar(Cmd, 0));
|
||||
if (strlen(Cmd) < 1 || ctmp == 'h') return usage_hf14_cgetsc();
|
||||
|
||||
sector = param_get8(Cmd, 0);
|
||||
if (sector > 39) {
|
||||
|
@ -2912,7 +2931,7 @@ int CmdHF14AMfCSave(const char *Cmd) {
|
|||
|
||||
if (errors || cmdp == 0) return usage_hf14_csave();
|
||||
|
||||
dump = malloc(bytes);
|
||||
dump = calloc(bytes, sizeof(uint8_t));
|
||||
if (!dump) {
|
||||
PrintAndLogEx(WARNING, "Fail, cannot allocate memory");
|
||||
return 1;
|
||||
|
@ -2958,8 +2977,8 @@ int CmdHF14AMfCSave(const char *Cmd) {
|
|||
//needs nt, ar, at, Data to decrypt
|
||||
int CmdHf14AMfDecryptBytes(const char *Cmd){
|
||||
|
||||
char ctmp = param_getchar(Cmd, 0);
|
||||
if (strlen(Cmd) < 1 || ctmp == 'h' || ctmp == 'H') return usage_hf14_decryptbytes();
|
||||
char ctmp = tolower(param_getchar(Cmd, 0));
|
||||
if (strlen(Cmd) < 1 || ctmp == 'h') return usage_hf14_decryptbytes();
|
||||
|
||||
uint32_t nt = param_get32ex(Cmd,0,0,16);
|
||||
uint32_t ar_enc = param_get32ex(Cmd,1,0,16);
|
||||
|
@ -3010,7 +3029,7 @@ int CmdHf14AMfSetMod(const char *Cmd) {
|
|||
UsbCommand resp;
|
||||
if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
|
||||
uint8_t ok = resp.arg[0] & 0xff;
|
||||
PrintAndLogEx(NORMAL, "isOk:%02x", ok);
|
||||
PrintAndLogEx(SUCCESS, "isOk:%02x", ok);
|
||||
if (!ok)
|
||||
PrintAndLogEx(FAILED, "Failed.");
|
||||
} else {
|
||||
|
@ -3023,12 +3042,12 @@ int CmdHf14AMfSetMod(const char *Cmd) {
|
|||
int CmdHf14AMfNack(const char *Cmd) {
|
||||
|
||||
bool verbose = false;
|
||||
char ctmp = param_getchar(Cmd, 0);
|
||||
if ( ctmp == 'h' || ctmp == 'H' ) return usage_hf14_nack();
|
||||
if ( ctmp == 'v' || ctmp == 'V' ) verbose = true;
|
||||
char ctmp = tolower(param_getchar(Cmd, 0));
|
||||
if ( ctmp == 'h' ) return usage_hf14_nack();
|
||||
if ( ctmp == 'v' ) verbose = true;
|
||||
|
||||
if ( verbose )
|
||||
PrintAndLogEx(NORMAL, "Started testing card for NACK bug. Press key to abort");
|
||||
PrintAndLogEx(INFO, "Started testing card for NACK bug. Press key to abort");
|
||||
|
||||
detect_classic_nackbug(verbose);
|
||||
return 0;
|
||||
|
@ -3086,7 +3105,7 @@ int CmdHF14AMfice(const char *Cmd) {
|
|||
PrintAndLogEx(NORMAL, "Collecting %u nonces \n", limit);
|
||||
|
||||
if ((fnonces = fopen(filename,"wb")) == NULL) {
|
||||
PrintAndLogEx(WARNING, "Could not create file %s",filename);
|
||||
PrintAndLogEx(WARNING, "Could not create file " _YELLOW_(%s),filename);
|
||||
return 3;
|
||||
}
|
||||
|
||||
|
@ -3097,7 +3116,7 @@ int CmdHF14AMfice(const char *Cmd) {
|
|||
do {
|
||||
if (ukbhit()) {
|
||||
int gc = getchar(); (void)gc;
|
||||
PrintAndLogEx(NORMAL, "\naborted via keyboard!\n");
|
||||
PrintAndLogEx(INFO, "\naborted via keyboard!\n");
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -3119,7 +3138,7 @@ int CmdHF14AMfice(const char *Cmd) {
|
|||
|
||||
total_num_nonces += items;
|
||||
if ( total_num_nonces > part_limit ) {
|
||||
PrintAndLogEx(NORMAL, "Total nonces %u\n", total_num_nonces);
|
||||
PrintAndLogEx(INFO, "Total nonces %u\n", total_num_nonces);
|
||||
part_limit += 3000;
|
||||
}
|
||||
|
||||
|
@ -3130,7 +3149,7 @@ int CmdHF14AMfice(const char *Cmd) {
|
|||
} while (!acquisition_completed);
|
||||
|
||||
out:
|
||||
PrintAndLogEx(NORMAL, "time: %" PRIu64 " seconds\n", (msclock()-t1)/1000);
|
||||
PrintAndLogEx(SUCCESS, "time: %" PRIu64 " seconds\n", (msclock()-t1)/1000);
|
||||
|
||||
if ( fnonces ) {
|
||||
fflush(fnonces);
|
||||
|
|
|
@ -209,7 +209,7 @@ static int compare_count_bitflip_bitarrays(const void *b1, const void *b2)
|
|||
|
||||
static voidpf inflate_malloc(voidpf opaque, uInt items, uInt size)
|
||||
{
|
||||
return malloc(items*size);
|
||||
return calloc(items*size, sizeof(uint8_t));
|
||||
}
|
||||
|
||||
|
||||
|
@ -1038,8 +1038,11 @@ static bool shrink_key_space(float *brute_forces)
|
|||
}
|
||||
*brute_forces = MIN(brute_forces1, brute_forces2);
|
||||
float reduction_rate = update_reduction_rate(*brute_forces, false);
|
||||
return ((hardnested_stage & CHECK_2ND_BYTES)
|
||||
&& reduction_rate >= 0.0 && reduction_rate < brute_force_per_second * sample_period / 1000.0);
|
||||
|
||||
//iceman 2018
|
||||
return ((hardnested_stage & CHECK_2ND_BYTES) &&
|
||||
reduction_rate >= 0.0 &&
|
||||
( reduction_rate < brute_force_per_second * (float)sample_period / 1000.0 || *brute_forces < 0x1F000000000));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -980,11 +980,11 @@ int CmdHF14AMfUInfo(const char *Cmd){
|
|||
if ( hasAuthKey ) return 1;
|
||||
|
||||
// also try to diversify default keys.. look into CmdHF14AMfuGenDiverseKeys
|
||||
PrintAndLogEx(NORMAL, "Trying some default 3des keys");
|
||||
PrintAndLogEx(INFO, "Trying some default 3des keys");
|
||||
for (uint8_t i = 0; i < KEYS_3DES_COUNT; ++i ) {
|
||||
key = default_3des_keys[i];
|
||||
if (ulc_authentication(key, true)) {
|
||||
PrintAndLogEx(NORMAL, "Found default 3des key: ");
|
||||
PrintAndLogEx(SUCCESS, "Found default 3des key: ");
|
||||
uint8_t keySwap[16];
|
||||
memcpy(keySwap, SwapEndian64(key,16,8), 16);
|
||||
ulc_print_3deskey(keySwap);
|
||||
|
@ -1079,7 +1079,7 @@ int CmdHF14AMfUInfo(const char *Cmd){
|
|||
num_to_bytes( ul_ev1_pwdgenA(card.uid), 4, key);
|
||||
len = ulev1_requestAuthentication(key, pack, sizeof(pack));
|
||||
if (len > -1) {
|
||||
PrintAndLogEx(NORMAL, "Found a default password: %s || Pack: %02X %02X",sprint_hex(key, 4), pack[0], pack[1]);
|
||||
PrintAndLogEx(SUCCESS, "Found a default password: %s || Pack: %02X %02X",sprint_hex(key, 4), pack[0], pack[1]);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -1089,7 +1089,7 @@ int CmdHF14AMfUInfo(const char *Cmd){
|
|||
num_to_bytes( ul_ev1_pwdgenB(card.uid), 4, key);
|
||||
len = ulev1_requestAuthentication(key, pack, sizeof(pack));
|
||||
if (len > -1) {
|
||||
PrintAndLogEx(NORMAL, "Found a default password: %s || Pack: %02X %02X",sprint_hex(key, 4), pack[0], pack[1]);
|
||||
PrintAndLogEx(SUCCESS, "Found a default password: %s || Pack: %02X %02X",sprint_hex(key, 4), pack[0], pack[1]);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -1099,7 +1099,7 @@ int CmdHF14AMfUInfo(const char *Cmd){
|
|||
num_to_bytes( ul_ev1_pwdgenC(card.uid), 4, key);
|
||||
len = ulev1_requestAuthentication(key, pack, sizeof(pack));
|
||||
if (len > -1) {
|
||||
PrintAndLogEx(NORMAL, "Found a default password: %s || Pack: %02X %02X",sprint_hex(key, 4), pack[0], pack[1]);
|
||||
PrintAndLogEx(SUCCESS, "Found a default password: %s || Pack: %02X %02X",sprint_hex(key, 4), pack[0], pack[1]);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -1109,7 +1109,7 @@ int CmdHF14AMfUInfo(const char *Cmd){
|
|||
num_to_bytes( ul_ev1_pwdgenD(card.uid), 4, key);
|
||||
len = ulev1_requestAuthentication(key, pack, sizeof(pack));
|
||||
if (len > -1) {
|
||||
PrintAndLogEx(NORMAL, "Found a default password: %s || Pack: %02X %02X",sprint_hex(key, 4), pack[0], pack[1]);
|
||||
PrintAndLogEx(SUCCESS, "Found a default password: %s || Pack: %02X %02X",sprint_hex(key, 4), pack[0], pack[1]);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -1119,13 +1119,13 @@ int CmdHF14AMfUInfo(const char *Cmd){
|
|||
key = default_pwd_pack[i];
|
||||
len = ulev1_requestAuthentication(key, pack, sizeof(pack));
|
||||
if (len > -1) {
|
||||
PrintAndLogEx(NORMAL, "Found a default password: %s || Pack: %02X %02X",sprint_hex(key, 4), pack[0], pack[1]);
|
||||
PrintAndLogEx(SUCCESS, "Found a default password: %s || Pack: %02X %02X",sprint_hex(key, 4), pack[0], pack[1]);
|
||||
break;
|
||||
} else {
|
||||
if (!ul_auth_select( &card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack))) return -1;
|
||||
}
|
||||
}
|
||||
if (len < 1) PrintAndLogEx(NORMAL, "password not known");
|
||||
if (len < 1) PrintAndLogEx(WARNING, "password not known");
|
||||
}
|
||||
}
|
||||
out:
|
||||
|
@ -1250,7 +1250,7 @@ int CmdHF14AMfUWrBl(const char *Cmd){
|
|||
UsbCommand resp;
|
||||
if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
|
||||
uint8_t isOK = resp.arg[0] & 0xff;
|
||||
PrintAndLogEx(NORMAL, "isOk:%02x", isOK);
|
||||
PrintAndLogEx(SUCCESS, "isOk:%02x", isOK);
|
||||
} else {
|
||||
PrintAndLogEx(WARNING, "Command execute timeout");
|
||||
}
|
||||
|
@ -1365,7 +1365,7 @@ int CmdHF14AMfURdBl(const char *Cmd){
|
|||
PrintAndLogEx(WARNING, "Failed reading block: (%02x)", isOK);
|
||||
}
|
||||
} else {
|
||||
PrintAndLogEx(NORMAL, "Command execute time-out");
|
||||
PrintAndLogEx(WARNING, "Command execute time-out");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -1743,7 +1743,7 @@ int CmdHF14AMfUDump(const char *Cmd){
|
|||
}
|
||||
}
|
||||
ul_print_type(tagtype, 0);
|
||||
PrintAndLogEx(NORMAL, "Reading tag memory...");
|
||||
PrintAndLogEx(SUCCESS, "Reading tag memory...");
|
||||
UsbCommand c = {CMD_MIFAREU_READCARD, {startPage, pages}};
|
||||
if ( hasAuthKey ) {
|
||||
if (tagtype & UL_C)
|
||||
|
@ -1912,12 +1912,10 @@ int CmdHF14AMfURestore(const char *Cmd){
|
|||
memset(authkey, 0x00, sizeof(authkey));
|
||||
|
||||
while(param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||
switch(param_getchar(Cmd, cmdp)) {
|
||||
switch (tolower(param_getchar(Cmd, cmdp))) {
|
||||
case 'h':
|
||||
case 'H':
|
||||
return usage_hf_mfu_restore();
|
||||
case 'k':
|
||||
case 'K':
|
||||
keylen = param_getstr(Cmd, cmdp+1, tempStr, sizeof(tempStr));
|
||||
if (keylen == 32 || keylen == 8) { //ul-c or ev1/ntag key length
|
||||
errors = param_gethex(tempStr, 0, authkey, keylen);
|
||||
|
@ -1930,12 +1928,10 @@ int CmdHF14AMfURestore(const char *Cmd){
|
|||
hasKey = true;
|
||||
break;
|
||||
case 'l':
|
||||
case 'L':
|
||||
swapEndian = true;
|
||||
cmdp++;
|
||||
break;
|
||||
case 'f':
|
||||
case 'F':
|
||||
filelen = param_getstr(Cmd, cmdp+1, filename, FILE_PATH_SIZE);
|
||||
|
||||
if (filelen > FILE_PATH_SIZE-5)
|
||||
|
@ -1947,17 +1943,14 @@ int CmdHF14AMfURestore(const char *Cmd){
|
|||
cmdp += 2;
|
||||
break;
|
||||
case 's':
|
||||
case 'S':
|
||||
cmdp++;
|
||||
write_special = true;
|
||||
break;
|
||||
case 'e':
|
||||
case 'E':
|
||||
cmdp++;
|
||||
write_extra = true;
|
||||
break;
|
||||
case 'r':
|
||||
case 'R':
|
||||
cmdp++;
|
||||
read_key = true;
|
||||
break;
|
||||
|
@ -1972,7 +1965,7 @@ int CmdHF14AMfURestore(const char *Cmd){
|
|||
if (errors || cmdp == 0) return usage_hf_mfu_restore();
|
||||
|
||||
if ((f = fopen(filename,"rb")) == NULL) {
|
||||
PrintAndLogEx(WARNING, "Could not find file %s", filename);
|
||||
PrintAndLogEx(WARNING, "Could not find file " _YELLOW_(%s), filename);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -2000,7 +1993,7 @@ int CmdHF14AMfURestore(const char *Cmd){
|
|||
return 1;
|
||||
}
|
||||
|
||||
PrintAndLogEx(NORMAL, "Restoring %s to card", filename);
|
||||
PrintAndLogEx(INFO, "Restoring " _YELLOW_(%s)" to card", filename);
|
||||
|
||||
mfu_dump_t *mem = (mfu_dump_t*)dump;
|
||||
uint8_t pages = (bytes_read-48)/4;
|
||||
|
@ -2084,7 +2077,7 @@ int CmdHF14AMfURestore(const char *Cmd){
|
|||
}
|
||||
}
|
||||
|
||||
PrintAndLogEx(NORMAL, "Restoring data blocks.");
|
||||
PrintAndLogEx(INFO, "Restoring data blocks.");
|
||||
// write all other data
|
||||
// Skip block 0,1,2,3 (only magic tags can write to them)
|
||||
// Skip last 5 blocks usually is configuration
|
||||
|
@ -2103,7 +2096,7 @@ int CmdHF14AMfURestore(const char *Cmd){
|
|||
// write special data last
|
||||
if (write_special) {
|
||||
|
||||
PrintAndLogEx(NORMAL, "Restoring configuration blocks.\n");
|
||||
PrintAndLogEx(INFO, "Restoring configuration blocks.\n");
|
||||
|
||||
PrintAndLogEx(NORMAL, "authentication with keytype[%x] %s\n", (uint8_t)(c.arg[1] & 0xff), sprint_hex(p_authkey,4));
|
||||
|
||||
|
@ -2128,16 +2121,16 @@ int CmdHF14AMfURestore(const char *Cmd){
|
|||
// Load emulator with dump file
|
||||
//
|
||||
int CmdHF14AMfUeLoad(const char *Cmd){
|
||||
char c = param_getchar(Cmd, 0);
|
||||
if ( c == 'h' || c == 'H' || c == 0x00) return usage_hf_mfu_eload();
|
||||
char c = tolower(param_getchar(Cmd, 0));
|
||||
if ( c == 'h' || c == 0x00) return usage_hf_mfu_eload();
|
||||
return CmdHF14AMfELoad(Cmd);
|
||||
}
|
||||
//
|
||||
// Simulate tag
|
||||
//
|
||||
int CmdHF14AMfUSim(const char *Cmd){
|
||||
char c = param_getchar(Cmd, 0);
|
||||
if ( c == 'h' || c == 'H' || c == 0x00) return usage_hf_mfu_sim();
|
||||
char c = tolower(param_getchar(Cmd, 0));
|
||||
if ( c == 'h' || c == 0x00) return usage_hf_mfu_sim();
|
||||
return CmdHF14ASim(Cmd);
|
||||
}
|
||||
|
||||
|
@ -2153,16 +2146,16 @@ int CmdHF14AMfucAuth(const char *Cmd){
|
|||
uint8_t keyNo = 3;
|
||||
bool errors = false;
|
||||
|
||||
char cmdp = param_getchar(Cmd, 0);
|
||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||
|
||||
//Change key to user defined one
|
||||
if (cmdp == 'k' || cmdp == 'K'){
|
||||
if (cmdp == 'k'){
|
||||
keyNo = param_get8(Cmd, 1);
|
||||
if(keyNo >= KEYS_3DES_COUNT)
|
||||
errors = true;
|
||||
}
|
||||
|
||||
if (cmdp == 'h' || cmdp == 'H') errors = true;
|
||||
if (cmdp == 'h') errors = true;
|
||||
|
||||
if (errors) return usage_hf_mfu_ucauth();
|
||||
|
||||
|
@ -2278,9 +2271,9 @@ int CmdTestDES(const char * cmd)
|
|||
int CmdHF14AMfucSetPwd(const char *Cmd){
|
||||
|
||||
uint8_t pwd[16] = {0x00};
|
||||
char cmdp = param_getchar(Cmd, 0);
|
||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||
|
||||
if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_hf_mfu_ucsetpwd();
|
||||
if (strlen(Cmd) == 0 || cmdp == 'h') return usage_hf_mfu_ucsetpwd();
|
||||
|
||||
if (param_gethex(Cmd, 0, pwd, 32)) {
|
||||
PrintAndLogEx(WARNING, "Password must include 32 HEX symbols");
|
||||
|
@ -2295,7 +2288,7 @@ int CmdHF14AMfucSetPwd(const char *Cmd){
|
|||
UsbCommand resp;
|
||||
if (WaitForResponseTimeout(CMD_ACK,&resp,1500) ) {
|
||||
if ( (resp.arg[0] & 0xff) == 1) {
|
||||
PrintAndLogEx(NORMAL, "Ultralight-C new password: %s", sprint_hex(pwd,16));
|
||||
PrintAndLogEx(INFO, "Ultralight-C new password: %s", sprint_hex(pwd,16));
|
||||
} else {
|
||||
PrintAndLogEx(WARNING, "Failed writing at block %d", resp.arg[1] & 0xff);
|
||||
return 1;
|
||||
|
@ -2315,9 +2308,9 @@ int CmdHF14AMfucSetUid(const char *Cmd){
|
|||
UsbCommand c = {CMD_MIFAREU_READBL};
|
||||
UsbCommand resp;
|
||||
uint8_t uid[7] = {0x00};
|
||||
char cmdp = param_getchar(Cmd, 0);
|
||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||
|
||||
if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_hf_mfu_ucsetuid();
|
||||
if (strlen(Cmd) == 0 || cmdp == 'h') return usage_hf_mfu_ucsetuid();
|
||||
|
||||
if (param_gethex(Cmd, 0, uid, 14)) {
|
||||
PrintAndLogEx(WARNING, "UID must include 14 HEX symbols");
|
||||
|
|
|
@ -194,7 +194,7 @@ static int topaz_print_CC(uint8_t *data) {
|
|||
PrintAndLogEx(NORMAL, " %02x: version %d.%d supported by tag", data[1], (data[1] & 0xF0) >> 4, data[1] & 0x0f);
|
||||
uint16_t memsize = (data[2] + 1) * 8;
|
||||
topaz_tag.size = memsize;
|
||||
topaz_tag.dynamic_memory = malloc(memsize - TOPAZ_STATIC_MEMORY);
|
||||
topaz_tag.dynamic_memory = calloc(memsize - TOPAZ_STATIC_MEMORY, sizeof(uint8_t));
|
||||
PrintAndLogEx(NORMAL, " %02x: Physical Memory Size of this tag: %d bytes", data[2], memsize);
|
||||
PrintAndLogEx(NORMAL, " %02x: %s / %s", data[3],
|
||||
(data[3] & 0xF0) ? "(RFU)" : "Read access granted without any security",
|
||||
|
@ -278,12 +278,12 @@ static void topaz_print_control_TLVs(uint8_t *memory) {
|
|||
dynamic_lock_area_t *old = topaz_tag.dynamic_lock_areas;
|
||||
dynamic_lock_area_t *new = topaz_tag.dynamic_lock_areas;
|
||||
if (old == NULL) {
|
||||
new = topaz_tag.dynamic_lock_areas = (dynamic_lock_area_t *)malloc(sizeof(dynamic_lock_area_t));
|
||||
new = topaz_tag.dynamic_lock_areas = (dynamic_lock_area_t *) calloc(sizeof(dynamic_lock_area_t) , sizeof(uint8_t));
|
||||
} else {
|
||||
while(old->next != NULL) {
|
||||
old = old->next;
|
||||
}
|
||||
new = old->next = (dynamic_lock_area_t *)malloc(sizeof(dynamic_lock_area_t));
|
||||
new = old->next = (dynamic_lock_area_t *) calloc(sizeof(dynamic_lock_area_t), sizeof(uint8_t));
|
||||
}
|
||||
new->next = NULL;
|
||||
if (area_start <= next_lockable_byte) {
|
||||
|
|
|
@ -257,9 +257,9 @@ int CmdVersion(const char *Cmd) {
|
|||
SendCommand(&c);
|
||||
if (WaitForResponseTimeout(CMD_ACK, &resp, 1000)) {
|
||||
#ifdef __WIN32
|
||||
PrintAndLogEx(NORMAL, "\nProxmark3 RFID instrument\n");
|
||||
PrintAndLogEx(NORMAL, "\n [ Proxmark3 RFID instrument ]\n");
|
||||
#else
|
||||
PrintAndLogEx(NORMAL, "\n\e[34mProxmark3 RFID instrument\e[0m\n");
|
||||
PrintAndLogEx(NORMAL, "\n\e[34m [ Proxmark3 RFID instrument ]\e[0m\n");
|
||||
#endif
|
||||
char s[50] = {0};
|
||||
#if defined(WITH_FLASH) || defined(WITH_SMARTCARD) || defined(WITH_FPC)
|
||||
|
@ -275,7 +275,7 @@ int CmdVersion(const char *Cmd) {
|
|||
strncat(s, "fpc; ", sizeof(s) - strlen(s) - 1);
|
||||
#endif
|
||||
PrintAndLogEx(NORMAL, "\n [ CLIENT ]");
|
||||
PrintAndLogEx(NORMAL, " client: iceman %s \n", s);
|
||||
PrintAndLogEx(NORMAL, " client: iceman %s \n", s);
|
||||
|
||||
PrintAndLogEx(NORMAL, (char*)resp.d.asBytes);
|
||||
lookupChipID(resp.arg[0], resp.arg[1]);
|
||||
|
|
|
@ -141,21 +141,33 @@ int usage_t55xx_wakup(){
|
|||
PrintAndLogEx(NORMAL, " lf t55xx wakeup p 11223344 - send wakeup password");
|
||||
return 0;
|
||||
}
|
||||
int usage_t55xx_bruteforce(){
|
||||
PrintAndLogEx(NORMAL, "This command uses A) bruteforce to scan a number range");
|
||||
PrintAndLogEx(NORMAL, " B) a dictionary attack");
|
||||
int usage_t55xx_chk(){
|
||||
PrintAndLogEx(NORMAL, "This command uses a dictionary attack");
|
||||
PrintAndLogEx(NORMAL, "press 'enter' to cancel the command");
|
||||
PrintAndLogEx(NORMAL, "Usage: lf t55xx bruteforce [h] <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, "Options:");
|
||||
PrintAndLogEx(NORMAL, " h - this help");
|
||||
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, " i <*.dic> - loads a default keys dictionary file <*.dic>");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "Examples:");
|
||||
PrintAndLogEx(NORMAL, " lf t55xx bruteforce aaaaaaaa bbbbbbbb");
|
||||
PrintAndLogEx(NORMAL, " lf t55xx bruteforce i default_pwd.dic");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
return 0;
|
||||
}
|
||||
|
@ -224,10 +236,9 @@ int CmdT55xxSetConfig(const char *Cmd) {
|
|||
uint8_t cmdp = 0;
|
||||
bool errors = false;
|
||||
while(param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||
tmp = param_getchar(Cmd, cmdp);
|
||||
tmp = tolower(param_getchar(Cmd, cmdp));
|
||||
switch(tmp) {
|
||||
case 'h':
|
||||
case 'H':
|
||||
return usage_t55xx_config();
|
||||
case 'b':
|
||||
errors |= param_getdec(Cmd, cmdp+1, &bitRate);
|
||||
|
@ -292,12 +303,10 @@ int CmdT55xxSetConfig(const char *Cmd) {
|
|||
config.offset = offset;
|
||||
cmdp+=2;
|
||||
break;
|
||||
case 'Q':
|
||||
case 'q':
|
||||
config.Q5 = true;
|
||||
cmdp++;
|
||||
break;
|
||||
case 'S':
|
||||
case 's':
|
||||
config.ST = true;
|
||||
cmdp++;
|
||||
|
@ -343,8 +352,8 @@ int T55xxReadBlock(uint8_t block, bool page1, bool usepwd, bool override, uint32
|
|||
if (!AquireData(page1, block, usepwd, password) ) return 0;
|
||||
if (!DecodeT55xxBlock()) return 0;
|
||||
|
||||
char blk[10]={0};
|
||||
sprintf(blk,"%02d", block);
|
||||
char blk[10] = {0};
|
||||
sprintf(blk, "%02d", block);
|
||||
printT55xxBlock(blk);
|
||||
return 1;
|
||||
}
|
||||
|
@ -358,22 +367,18 @@ int CmdT55xxReadBlock(const char *Cmd) {
|
|||
bool errors = false;
|
||||
uint8_t cmdp = 0;
|
||||
while(param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||
switch(param_getchar(Cmd, cmdp)) {
|
||||
switch ( tolower(param_getchar(Cmd, cmdp))) {
|
||||
case 'h':
|
||||
case 'H':
|
||||
return usage_t55xx_read();
|
||||
case 'b':
|
||||
case 'B':
|
||||
errors |= param_getdec(Cmd, cmdp+1, &block);
|
||||
cmdp += 2;
|
||||
break;
|
||||
case 'o':
|
||||
case 'O':
|
||||
override = true;
|
||||
cmdp++;
|
||||
break;
|
||||
case 'p':
|
||||
case 'P':
|
||||
password = param_get32ex(Cmd, cmdp+1, 0, 16);
|
||||
usepwd = true;
|
||||
cmdp += 2;
|
||||
|
@ -1503,23 +1508,68 @@ bool IsCancelled(void) {
|
|||
return false;
|
||||
}
|
||||
|
||||
int CmdT55xxBruteForce(const char *Cmd) {
|
||||
|
||||
int CmdT55xxChkPwds(const char *Cmd) {
|
||||
// load a default pwd file.
|
||||
char line[9];
|
||||
char filename[FILE_PATH_SIZE] = {0};
|
||||
int keycnt = 0;
|
||||
uint8_t stKeyBlock = 20;
|
||||
uint8_t *keyBlock = NULL, *p = NULL;
|
||||
uint32_t start_password = 0x00000000; //start password
|
||||
uint32_t end_password = 0xFFFFFFFF; //end password
|
||||
bool found = false;
|
||||
uint8_t timeout = 0;
|
||||
|
||||
memset(line, 0, sizeof(line));
|
||||
|
||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||
if (cmdp == 'h') return usage_t55xx_bruteforce();
|
||||
if (cmdp == 'h') return usage_t55xx_chk();
|
||||
|
||||
/*
|
||||
if ( T55xxReadBlock(7, 0, 0, 0, 0) ) {
|
||||
|
||||
// now try to validate it..
|
||||
PrintAndLogEx(WARNING, "\n Block 7 was readable");
|
||||
return 1;
|
||||
}
|
||||
*/
|
||||
|
||||
uint64_t t1 = msclock();
|
||||
|
||||
if ( cmdp == 'm' ) {
|
||||
UsbCommand c = {CMD_T55XX_CHKPWDS, {0,0,0} };
|
||||
clearCommandBuffer();
|
||||
SendCommand(&c);
|
||||
UsbCommand resp;
|
||||
|
||||
while ( !WaitForResponseTimeout(CMD_ACK, &resp, 2000) ) {
|
||||
timeout++;
|
||||
printf("."); fflush(stdout);
|
||||
if (timeout > 180) {
|
||||
PrintAndLogEx(WARNING, "\nno response from Proxmark. Aborting...");
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
if ( resp.arg[0] ) {
|
||||
PrintAndLogEx(SUCCESS, "\nFound a candidate [ %08X ]. Trying to validate", resp.arg[1]);
|
||||
|
||||
if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, resp.arg[1])) {
|
||||
PrintAndLogEx(INFO, "Aquireing data from device failed. Quitting");
|
||||
return 2;
|
||||
}
|
||||
|
||||
found = tryDetectModulation();
|
||||
if (found) {
|
||||
PrintAndLogEx(SUCCESS, "Found valid password: [ %08X ]", resp.arg[1]);
|
||||
} else {
|
||||
PrintAndLogEx(WARNING, "Password NOT found.");
|
||||
}
|
||||
} else {
|
||||
PrintAndLogEx(WARNING, "Password NOT found.");
|
||||
}
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
keyBlock = calloc(stKeyBlock, 4);
|
||||
if (keyBlock == NULL) return 1;
|
||||
|
||||
|
@ -1531,7 +1581,7 @@ int CmdT55xxBruteForce(const char *Cmd) {
|
|||
|
||||
FILE * f = fopen( filename , "r");
|
||||
if ( !f ) {
|
||||
PrintAndLogEx(NORMAL, "File: %s: not found or locked.", filename);
|
||||
PrintAndLogEx(WARNING, "File: %s: not found or locked.", filename);
|
||||
free(keyBlock);
|
||||
return 1;
|
||||
}
|
||||
|
@ -1546,7 +1596,7 @@ int CmdT55xxBruteForce(const char *Cmd) {
|
|||
if( line[0]=='#' ) continue;
|
||||
|
||||
if (!isxdigit(line[0])) {
|
||||
PrintAndLogEx(NORMAL, "File content error. '%s' must include 8 HEX symbols", line);
|
||||
PrintAndLogEx(WARNING, "File content error. '%s' must include 8 HEX symbols", line);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1569,7 +1619,7 @@ int CmdT55xxBruteForce(const char *Cmd) {
|
|||
|
||||
num_to_bytes( strtoll(line, NULL, 16), 4, keyBlock + 4*keycnt);
|
||||
|
||||
PrintAndLogEx(NORMAL, "chk custom pwd[%2d] %08X", keycnt, bytes_to_num(keyBlock + 4 * keycnt, 4) );
|
||||
// PrintAndLogEx(NORMAL, "chk custom pwd[%2d] %08X", keycnt, bytes_to_num(keyBlock + 4 * keycnt, 4) );
|
||||
keycnt++;
|
||||
memset(line, 0, sizeof(line));
|
||||
}
|
||||
|
@ -1577,11 +1627,11 @@ int CmdT55xxBruteForce(const char *Cmd) {
|
|||
fclose(f);
|
||||
|
||||
if (keycnt == 0) {
|
||||
PrintAndLogEx(NORMAL, "No keys found in file");
|
||||
PrintAndLogEx(WARNING, "No keys found in file");
|
||||
free(keyBlock);
|
||||
return 1;
|
||||
}
|
||||
PrintAndLogEx(NORMAL, "Loaded %d keys", keycnt);
|
||||
PrintAndLogEx(SUCCESS, "Loaded %d keys", keycnt);
|
||||
|
||||
// loop
|
||||
uint64_t testpwd = 0x00;
|
||||
|
@ -1600,69 +1650,87 @@ int CmdT55xxBruteForce(const char *Cmd) {
|
|||
|
||||
testpwd = bytes_to_num(keyBlock + 4*c, 4);
|
||||
|
||||
PrintAndLogEx(NORMAL, "Testing %08X", testpwd);
|
||||
PrintAndLogEx(INFO, "Testing %08X", testpwd);
|
||||
|
||||
if ( !AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, testpwd)) {
|
||||
PrintAndLogEx(NORMAL, "Aquireing data from device failed. Quitting");
|
||||
PrintAndLogEx(INFO, "Aquireing data from device failed. Quitting");
|
||||
free(keyBlock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
found = tryDetectModulation();
|
||||
if ( found ) {
|
||||
PrintAndLogEx(NORMAL, "Found valid password: [%08X]", testpwd);
|
||||
//free(keyBlock);
|
||||
//return 0;
|
||||
}
|
||||
if ( found )
|
||||
break;
|
||||
|
||||
}
|
||||
PrintAndLogEx(NORMAL, "Password NOT found.");
|
||||
free(keyBlock);
|
||||
return 0;
|
||||
if ( found )
|
||||
PrintAndLogEx(SUCCESS, "Found valid password: [ %08X ]", testpwd);
|
||||
else
|
||||
PrintAndLogEx(WARNING, "Password NOT found.");
|
||||
}
|
||||
|
||||
free(keyBlock);
|
||||
|
||||
out:
|
||||
t1 = msclock() - t1;
|
||||
PrintAndLogEx(SUCCESS, "\nTime in bruteforce: %.0f seconds\n", (float)t1/1000.0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdT55xxBruteForce(const char *Cmd) {
|
||||
|
||||
uint32_t start_password = 0x00000000; //start password
|
||||
uint32_t end_password = 0xFFFFFFFF; //end password
|
||||
uint32_t curr = 0;
|
||||
bool found = false;
|
||||
|
||||
|
||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||
if (cmdp == 'h') return usage_t55xx_bruteforce();
|
||||
|
||||
uint64_t t1 = msclock();
|
||||
|
||||
// Try to read Block 7, first :)
|
||||
|
||||
// incremental pwd range search
|
||||
start_password = param_get32ex(Cmd, 0, 0, 16);
|
||||
end_password = param_get32ex(Cmd, 1, 0, 16);
|
||||
|
||||
curr = start_password;
|
||||
|
||||
if ( start_password >= end_password ) {
|
||||
free(keyBlock);
|
||||
return usage_t55xx_bruteforce();
|
||||
}
|
||||
|
||||
PrintAndLogEx(NORMAL, "Search password range [%08X -> %08X]", start_password, end_password);
|
||||
|
||||
uint32_t i = start_password;
|
||||
PrintAndLogEx(INFO, "Search password range [%08X -> %08X]", start_password, end_password);
|
||||
|
||||
while ((!found) && (i <= end_password)){
|
||||
while ((!found) || (curr <= end_password)){
|
||||
|
||||
printf("."); fflush(stdout);
|
||||
|
||||
if (IsCancelled()) {
|
||||
free(keyBlock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, i)) {
|
||||
PrintAndLogEx(NORMAL, "Aquireing data from device failed. Quitting");
|
||||
free(keyBlock);
|
||||
if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, curr)) {
|
||||
PrintAndLogEx(WARNING, "Aquireing data from device failed. Quitting");
|
||||
return 0;
|
||||
}
|
||||
found = tryDetectModulation();
|
||||
|
||||
if (found) break;
|
||||
i++;
|
||||
++curr;
|
||||
}
|
||||
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
|
||||
if (found)
|
||||
PrintAndLogEx(NORMAL, "Found valid password: [%08x]", i);
|
||||
PrintAndLogEx(SUCCESS, "Found valid password: [ %08X ]", curr);
|
||||
else
|
||||
PrintAndLogEx(NORMAL, "Password NOT found. Last tried: [%08x]", --i);
|
||||
PrintAndLogEx(WARNING, "Password NOT found. Last tried: [ %08X ]", --curr);
|
||||
|
||||
free(keyBlock);
|
||||
t1 = msclock() - t1;
|
||||
PrintAndLogEx(SUCCESS, "\nTime in bruteforce: %.0f seconds\n", (float)t1/1000.0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1746,9 +1814,9 @@ int CmdT55xxRecoverPW(const char *Cmd) {
|
|||
PrintAndLogEx(NORMAL, "");
|
||||
|
||||
if (found == 1)
|
||||
PrintAndLogEx(NORMAL, "Found valid password: [%08x]", curr_password);
|
||||
PrintAndLogEx(SUCCESS, "Found valid password: [%08x]", curr_password);
|
||||
else
|
||||
PrintAndLogEx(NORMAL, "Password NOT found.");
|
||||
PrintAndLogEx(WARNING, "Password NOT found.");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1959,6 +2027,7 @@ static command_t CommandTable[] = {
|
|||
{"help", CmdHelp, 1, "This help"},
|
||||
{"bruteforce", CmdT55xxBruteForce,0, "<start password> <end password> [i <*.dic>] Simple bruteforce attack to find password"},
|
||||
{"config", CmdT55xxSetConfig, 1, "Set/Get T55XX configuration (modulation, inverted, offset, rate)"},
|
||||
{"chk", CmdT55xxChkPwds, 1, "Check passwords"},
|
||||
{"detect", CmdT55xxDetect, 1, "[1] Try detecting the tag modulation from reading the configuration block."},
|
||||
{"deviceconfig", CmdT55xxSetDeviceConfig, 1, "Set/Get T55XX device configuration (startgap, writegap, write0, write1, readgap"},
|
||||
{"p1detect", CmdT55xxDetectPage1,1, "[1] Try detecting if this is a t55xx tag by reading page 1"},
|
||||
|
|
|
@ -133,6 +133,7 @@ t55xx_conf_block_t Get_t55xx_Config(void);
|
|||
void Set_t55xx_Config(t55xx_conf_block_t conf);
|
||||
|
||||
extern int CmdLFT55XX(const char *Cmd);
|
||||
extern int CmdT55xxChk(const char *Cmd);
|
||||
extern int CmdT55xxBruteForce(const char *Cmd);
|
||||
extern int CmdT55xxSetConfig(const char *Cmd);
|
||||
extern int CmdT55xxReadBlock(const char *Cmd);
|
||||
|
|
|
@ -356,7 +356,7 @@ static int smart_responseEx(uint8_t *data, bool silent) {
|
|||
if (needGetData) {
|
||||
int len = data[datalen - 1];
|
||||
if (!silent) PrintAndLogEx(INFO, "Requesting 0x%02X bytes response", len);
|
||||
uint8_t getstatus[] = {0x00, ISO7816_GETSTATUS, 0x00, 0x00, len};
|
||||
uint8_t getstatus[] = {0x00, ISO7816_GET_RESPONSE, 0x00, 0x00, len};
|
||||
UsbCommand cStatus = {CMD_SMART_RAW, {SC_RAW, sizeof(getstatus), 0}};
|
||||
memcpy(cStatus.d.asBytes, getstatus, sizeof(getstatus) );
|
||||
clearCommandBuffer();
|
||||
|
@ -372,7 +372,7 @@ static int smart_responseEx(uint8_t *data, bool silent) {
|
|||
if (datalen != len + 2) {
|
||||
// data with ACK
|
||||
if (datalen == len + 2 + 1) { // 2 - response, 1 - ACK
|
||||
if (data[0] != ISO7816_GETSTATUS) {
|
||||
if (data[0] != ISO7816_GET_RESPONSE) {
|
||||
if (!silent) {
|
||||
PrintAndLogEx(ERR, "GetResponse ACK error. len 0x%x | data[0] %02X", len, data[0]);
|
||||
}
|
||||
|
@ -1012,7 +1012,7 @@ int CmdSmartBruteforceSFI(const char *Cmd) {
|
|||
json_t *root = NULL;
|
||||
smart_loadjson("aidlist", "json", &root);
|
||||
|
||||
uint8_t* buf = malloc(USB_CMD_DATA_SIZE);
|
||||
uint8_t* buf = calloc(USB_CMD_DATA_SIZE, sizeof(uint8_t));
|
||||
if ( !buf )
|
||||
return 1;
|
||||
|
||||
|
|
|
@ -711,4 +711,47 @@ FD8705E721B0,
|
|||
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,
|
||||
|
|
|
@ -96,6 +96,7 @@ FABADA11, //china?
|
|||
69696969,
|
||||
12121212,
|
||||
12344321,
|
||||
1234ABCD,
|
||||
11112222,
|
||||
13131313,
|
||||
10041004,
|
||||
|
@ -104,8 +105,8 @@ FABADA11, //china?
|
|||
abcd1234,
|
||||
20002000,
|
||||
19721972,
|
||||
aa55aa55, //amiboo
|
||||
55aa55aa, //rev amiboo
|
||||
aa55aa55, // amiboo
|
||||
55aa55aa, // rev amiboo
|
||||
4f271149, // seeds ul-ev1
|
||||
07d7bb0b, // seeds ul-ev1
|
||||
9636ef8f, // seeds ul-ev1
|
||||
|
@ -113,4 +114,4 @@ b5f44686, // seeds ul-ev1
|
|||
9E3779B9, // TEA
|
||||
C6EF3720, // TEA
|
||||
7854794A, // xbox tea constant :)
|
||||
F1EA5EED, //burtle
|
||||
F1EA5EED, // burtle
|
||||
|
|
1000
client/dictionaries/bmp_sort_keys.dic
Normal file
1000
client/dictionaries/bmp_sort_keys.dic
Normal file
File diff suppressed because it is too large
Load diff
1001
client/dictionaries/icbpm_sort_keys.dic
Normal file
1001
client/dictionaries/icbpm_sort_keys.dic
Normal file
File diff suppressed because it is too large
Load diff
57
client/dictionaries/mrzd_sort_keys.dic
Normal file
57
client/dictionaries/mrzd_sort_keys.dic
Normal 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,
|
|
@ -623,7 +623,7 @@ int CmdEMVInternalAuthenticate(const char *cmd) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
#define dreturn(n) {free(pdol_data_tlv);tlvdb_free(tlvSelect);tlvdb_free(tlvRoot);DropField();return n;}
|
||||
#define dreturn(n) {free(pdol_data_tlv); tlvdb_free(tlvSelect); tlvdb_free(tlvRoot); DropFieldEx( channel ); return n;}
|
||||
|
||||
void InitTransactionParameters(struct tlvdb *tlvRoot, bool paramLoadJSON, enum TransactionType TrType, bool GenACGPO) {
|
||||
|
||||
|
@ -1244,7 +1244,7 @@ int CmdEMVExec(const char *cmd) {
|
|||
|
||||
}
|
||||
|
||||
DropField();
|
||||
DropFieldEx( channel );
|
||||
|
||||
// Destroy TLV's
|
||||
free(pdol_data_tlv);
|
||||
|
@ -1346,7 +1346,7 @@ int CmdEMVScan(const char *cmd) {
|
|||
}
|
||||
|
||||
// drop field at start
|
||||
DropField();
|
||||
DropFieldEx( channel );
|
||||
|
||||
// iso 14443 select
|
||||
PrintAndLogEx(NORMAL, "--> GET UID, ATS.");
|
||||
|
@ -1399,7 +1399,7 @@ int CmdEMVScan(const char *cmd) {
|
|||
if (EMVSearch(channel, false, true, decodeTLV, tlvSelect)) {
|
||||
PrintAndLogEx(ERR, "Can't found any of EMV AID. Exit...");
|
||||
tlvdb_free(tlvSelect);
|
||||
DropField();
|
||||
DropFieldEx( channel );
|
||||
return 3;
|
||||
}
|
||||
|
||||
|
@ -1415,7 +1415,7 @@ int CmdEMVScan(const char *cmd) {
|
|||
|
||||
if (!AIDlen) {
|
||||
PrintAndLogEx(INFO, "Can't select AID. EMV AID not found. Exit...");
|
||||
DropField();
|
||||
DropFieldEx( channel );
|
||||
return 4;
|
||||
}
|
||||
|
||||
|
@ -1434,7 +1434,7 @@ int CmdEMVScan(const char *cmd) {
|
|||
if (res) {
|
||||
PrintAndLogEx(ERR, "Can't select AID (%d). Exit...", res);
|
||||
tlvdb_free(tlvRoot);
|
||||
DropField();
|
||||
DropFieldEx( channel );
|
||||
return 5;
|
||||
}
|
||||
|
||||
|
@ -1462,7 +1462,7 @@ int CmdEMVScan(const char *cmd) {
|
|||
if (!pdol_data_tlv){
|
||||
PrintAndLogEx(ERR, "Can't create PDOL TLV.");
|
||||
tlvdb_free(tlvRoot);
|
||||
DropField();
|
||||
DropFieldEx( channel );
|
||||
return 6;
|
||||
}
|
||||
|
||||
|
@ -1471,7 +1471,7 @@ int CmdEMVScan(const char *cmd) {
|
|||
if (!pdol_data_tlv_data) {
|
||||
PrintAndLogEx(ERR, "Can't create PDOL data.");
|
||||
tlvdb_free(tlvRoot);
|
||||
DropField();
|
||||
DropFieldEx( channel );
|
||||
return 6;
|
||||
}
|
||||
PrintAndLogEx(INFO, "PDOL data[%d]: %s", pdol_data_tlv_data_len, sprint_hex(pdol_data_tlv_data, pdol_data_tlv_data_len));
|
||||
|
@ -1485,7 +1485,7 @@ int CmdEMVScan(const char *cmd) {
|
|||
if (res) {
|
||||
PrintAndLogEx(ERR, "GPO error(%d): %4x. Exit...", res, sw);
|
||||
tlvdb_free(tlvRoot);
|
||||
DropField();
|
||||
DropFieldEx( channel );
|
||||
return 7;
|
||||
}
|
||||
ProcessGPOResponseFormat1(tlvRoot, buf, len, decodeTLV);
|
||||
|
@ -1577,8 +1577,7 @@ int CmdEMVScan(const char *cmd) {
|
|||
// free tlv object
|
||||
tlvdb_free(tlvRoot);
|
||||
|
||||
// DropField
|
||||
DropField();
|
||||
DropFieldEx( channel );
|
||||
|
||||
res = json_dump_file(root, fname, JSON_INDENT(2));
|
||||
if (res) {
|
||||
|
@ -1631,6 +1630,14 @@ int CmdEMVRoca(const char *cmd) {
|
|||
if (arg_get_lit(2))
|
||||
channel = ECC_CONTACT;
|
||||
PrintChannel(channel);
|
||||
|
||||
#ifndef WITH_SMARTCARD
|
||||
// not compiled with smartcard functionality, we need to exit
|
||||
if ( channel == ECC_CONTACT ) {
|
||||
PrintAndLogEx(WARNING, "PM3 Client is not compiled with support for SMARTCARD. Exiting.");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
// select card
|
||||
uint8_t psenum = (channel == ECC_CONTACT) ? 1 : 2;
|
||||
|
@ -1654,7 +1661,7 @@ int CmdEMVRoca(const char *cmd) {
|
|||
if (EMVSearch(channel, false, true, false, tlvSelect)) {
|
||||
PrintAndLogEx(ERR, "Can't found any of EMV AID. Exit...");
|
||||
tlvdb_free(tlvSelect);
|
||||
DropField();
|
||||
DropFieldEx( channel );
|
||||
return 3;
|
||||
}
|
||||
|
||||
|
@ -1670,7 +1677,7 @@ int CmdEMVRoca(const char *cmd) {
|
|||
|
||||
if (!AIDlen) {
|
||||
PrintAndLogEx(INFO, "Can't select AID. EMV AID not found. Exit...");
|
||||
DropField();
|
||||
DropFieldEx( channel );
|
||||
return 4;
|
||||
}
|
||||
|
||||
|
@ -1685,7 +1692,7 @@ int CmdEMVRoca(const char *cmd) {
|
|||
if (res) {
|
||||
PrintAndLogEx(ERR, "Can't select AID (%d). Exit...", res);
|
||||
tlvdb_free(tlvRoot);
|
||||
DropField();
|
||||
DropFieldEx( channel );
|
||||
return 5;
|
||||
}
|
||||
|
||||
|
@ -1697,7 +1704,7 @@ int CmdEMVRoca(const char *cmd) {
|
|||
if (!pdol_data_tlv){
|
||||
PrintAndLogEx(ERR, "Can't create PDOL TLV.");
|
||||
tlvdb_free(tlvRoot);
|
||||
DropField();
|
||||
DropFieldEx( channel );
|
||||
return 6;
|
||||
}
|
||||
|
||||
|
@ -1706,7 +1713,7 @@ int CmdEMVRoca(const char *cmd) {
|
|||
if (!pdol_data_tlv_data) {
|
||||
PrintAndLogEx(ERR, "Can't create PDOL data.");
|
||||
tlvdb_free(tlvRoot);
|
||||
DropField();
|
||||
DropFieldEx( channel );
|
||||
return 6;
|
||||
}
|
||||
PrintAndLogEx(INFO, "PDOL data[%d]: %s", pdol_data_tlv_data_len, sprint_hex(pdol_data_tlv_data, pdol_data_tlv_data_len));
|
||||
|
@ -1720,7 +1727,7 @@ int CmdEMVRoca(const char *cmd) {
|
|||
if (res) {
|
||||
PrintAndLogEx(ERR, "GPO error(%d): %4x. Exit...", res, sw);
|
||||
tlvdb_free(tlvRoot);
|
||||
DropField();
|
||||
DropFieldEx( channel );
|
||||
return 7;
|
||||
}
|
||||
ProcessGPOResponseFormat1(tlvRoot, buf, len, false);
|
||||
|
@ -1818,10 +1825,7 @@ out:
|
|||
// free tlv object
|
||||
tlvdb_free(tlvRoot);
|
||||
|
||||
if ( channel == ECC_CONTACTLESS)
|
||||
DropField();
|
||||
|
||||
|
||||
DropFieldEx( channel );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -241,7 +241,7 @@ int EMVExchangeEx(EMVCommandChannel channel, bool ActivateField, bool LeaveField
|
|||
int res = 0;
|
||||
|
||||
if (ActivateField) {
|
||||
DropField();
|
||||
DropFieldEx( channel );
|
||||
msleep(50);
|
||||
}
|
||||
|
||||
|
@ -262,8 +262,12 @@ int EMVExchangeEx(EMVCommandChannel channel, bool ActivateField, bool LeaveField
|
|||
}
|
||||
break;
|
||||
case ECC_CONTACT:
|
||||
#ifdef WITH_SMARTCARD
|
||||
//int ExchangeAPDUSC(uint8_t *datain, int datainlen, bool activateCard, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen);
|
||||
res = ExchangeAPDUSC(data, (IncludeLe?6:5) + apdu.Lc, ActivateField, LeaveFieldON, Result, (int)MaxResultLen, (int *)ResultLen);
|
||||
#else
|
||||
res = 1;
|
||||
#endif
|
||||
if (res) {
|
||||
return res;
|
||||
}
|
||||
|
@ -480,7 +484,7 @@ int EMVSearchPSE(EMVCommandChannel channel, bool ActivateField, bool LeaveFieldO
|
|||
}
|
||||
|
||||
if(!LeaveFieldON)
|
||||
DropField();
|
||||
DropFieldEx( channel );
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -58,6 +58,23 @@
|
|||
"U9psmyPzK+Vsgw2jeRQ5JlKDyqE0hebfC1tvFu0CCrJFcw==\r\n" \
|
||||
"-----END CERTIFICATE-----\r\n"
|
||||
|
||||
// Name: SoloKey U2F Root CA Serial 14143382635911888524 (0xc44763928ff4be8c)
|
||||
// Issued: 2018-11-11
|
||||
#define SOLOKEY_CA \
|
||||
"-----BEGIN CERTIFICATE-----\r\n" \
|
||||
"MIIB9DCCAZoCCQDER2OSj/S+jDAKBggqhkjOPQQDAjCBgDELMAkGA1UEBhMCVVMx\r\n" \
|
||||
"ETAPBgNVBAgMCE1hcnlsYW5kMRIwEAYDVQQKDAlTb2xvIEtleXMxEDAOBgNVBAsM\r\n" \
|
||||
"B1Jvb3QgQ0ExFTATBgNVBAMMDHNvbG9rZXlzLmNvbTEhMB8GCSqGSIb3DQEJARYS\r\n" \
|
||||
"aGVsbG9Ac29sb2tleXMuY29tMCAXDTE4MTExMTEyNTE0MloYDzIwNjgxMDI5MTI1\r\n" \
|
||||
"MTQyWjCBgDELMAkGA1UEBhMCVVMxETAPBgNVBAgMCE1hcnlsYW5kMRIwEAYDVQQK\r\n" \
|
||||
"DAlTb2xvIEtleXMxEDAOBgNVBAsMB1Jvb3QgQ0ExFTATBgNVBAMMDHNvbG9rZXlz\r\n" \
|
||||
"LmNvbTEhMB8GCSqGSIb3DQEJARYSaGVsbG9Ac29sb2tleXMuY29tMFkwEwYHKoZI\r\n" \
|
||||
"zj0CAQYIKoZIzj0DAQcDQgAEWHAN0CCJVZdMs0oktZ5m93uxmB1iyq8ELRLtqVFL\r\n" \
|
||||
"SOiHQEab56qRTB/QzrpGAY++Y2mw+vRuQMNhBiU0KzwjBjAKBggqhkjOPQQDAgNI\r\n" \
|
||||
"ADBFAiEAz9SlrAXIlEu87vra54rICPs+4b0qhp3PdzcTg7rvnP0CIGjxzlteQQx+\r\n" \
|
||||
"jQGd7rwSZuE5RWUPVygYhUstQO9zNUOs\r\n" \
|
||||
"-----END CERTIFICATE-----\r\n"
|
||||
|
||||
/* Concatenation of all additional CA certificates in PEM format if available */
|
||||
const char additional_ca_pem[] = GLOBALSIGN_CA YUBICO_CA;
|
||||
const char additional_ca_pem[] = GLOBALSIGN_CA YUBICO_CA SOLOKEY_CA;
|
||||
const size_t additional_ca_pem_len = sizeof(additional_ca_pem);
|
||||
|
|
|
@ -250,9 +250,9 @@ int FIDOCheckDERAndGetKey(uint8_t *der, size_t derLen, bool verbose, uint8_t *pu
|
|||
uint32_t verifyflags = 0;
|
||||
res = mbedtls_x509_crt_verify(&cert, &cacert, NULL, NULL, &verifyflags, NULL, NULL);
|
||||
if (res) {
|
||||
PrintAndLog("ERROR: DER verify returned 0x%x - %s", (res<0)?-res:res, ecdsa_get_error(res));
|
||||
PrintAndLog("ERROR: DER verify returned 0x%x - %s\n", (res<0)?-res:res, ecdsa_get_error(res));
|
||||
} else {
|
||||
PrintAndLog("Certificate OK.");
|
||||
PrintAndLog("Certificate OK.\n");
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
|
|
|
@ -38,7 +38,7 @@ static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs,
|
|||
flash_seg_t *seg;
|
||||
uint32_t last_end = 0;
|
||||
|
||||
ctx->segments = malloc(sizeof(flash_seg_t) * num_phdrs);
|
||||
ctx->segments = calloc(sizeof(flash_seg_t) * num_phdrs, sizeof(uint8_t));
|
||||
if (!ctx->segments) {
|
||||
fprintf(stderr, "Out of memory\n");
|
||||
return -1;
|
||||
|
@ -88,7 +88,7 @@ static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs,
|
|||
|
||||
uint8_t *data;
|
||||
// make extra space if we need to move the data forward
|
||||
data = malloc(filesz + BLOCK_SIZE);
|
||||
data = calloc(filesz + BLOCK_SIZE, sizeof(uint8_t));
|
||||
if (!data) {
|
||||
fprintf(stderr, "Error: Out of memory\n");
|
||||
return -1;
|
||||
|
@ -111,7 +111,7 @@ static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs,
|
|||
uint32_t new_length = this_end - prev_seg->start;
|
||||
uint32_t this_offset = paddr - prev_seg->start;
|
||||
uint32_t hole = this_offset - prev_seg->length;
|
||||
uint8_t *new_data = malloc(new_length);
|
||||
uint8_t *new_data = calloc(new_length, sizeof(uint8_t));
|
||||
if (!new_data) {
|
||||
fprintf(stderr, "Error: Out of memory\n");
|
||||
free(data);
|
||||
|
@ -223,7 +223,7 @@ int flash_load(flash_file_t *ctx, const char *name, int can_write_bl) {
|
|||
}
|
||||
num_phdrs = le16(ehdr.e_phnum);
|
||||
|
||||
phdrs = malloc(le16(ehdr.e_phnum) * sizeof(Elf32_Phdr));
|
||||
phdrs = calloc(le16(ehdr.e_phnum) * sizeof(Elf32_Phdr), sizeof(uint8_t));
|
||||
if (!phdrs) {
|
||||
fprintf(stderr, "Out of memory\n");
|
||||
goto fail;
|
||||
|
|
|
@ -59,7 +59,7 @@ static void usage(void)
|
|||
|
||||
static voidpf fpga_deflate_malloc(voidpf opaque, uInt items, uInt size)
|
||||
{
|
||||
return malloc(items*size);
|
||||
return calloc(items*size, sizeof(uint8_t));
|
||||
}
|
||||
|
||||
|
||||
|
@ -89,9 +89,9 @@ int zlib_compress(FILE *infile[], uint8_t num_infiles, FILE *outfile, bool hardn
|
|||
z_stream compressed_fpga_stream;
|
||||
|
||||
if (hardnested_mode) {
|
||||
fpga_config = malloc(num_infiles * HARDNESTED_TABLE_SIZE);
|
||||
fpga_config = calloc(num_infiles * HARDNESTED_TABLE_SIZE, sizeof(uint8_t));
|
||||
} else {
|
||||
fpga_config = malloc(num_infiles * FPGA_CONFIG_SIZE);
|
||||
fpga_config = calloc(num_infiles * FPGA_CONFIG_SIZE, sizeof(uint8_t));
|
||||
}
|
||||
// read the input files. Interleave them into fpga_config[]
|
||||
i = 0;
|
||||
|
|
|
@ -40,7 +40,7 @@ static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs,
|
|||
flash_seg_t *seg;
|
||||
uint32_t last_end = 0;
|
||||
|
||||
ctx->segments = malloc(sizeof(flash_seg_t) * num_phdrs);
|
||||
ctx->segments = calloc(sizeof(flash_seg_t) * num_phdrs, sizeof(uint8_t));
|
||||
if (!ctx->segments) {
|
||||
fprintf(stderr, "Out of memory\n");
|
||||
return -1;
|
||||
|
@ -90,7 +90,7 @@ static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs,
|
|||
|
||||
uint8_t *data;
|
||||
// make extra space if we need to move the data forward
|
||||
data = malloc(filesz + BLOCK_SIZE);
|
||||
data = calloc(filesz + BLOCK_SIZE, sizeof(uint8_t));
|
||||
if (!data) {
|
||||
fprintf(stderr, "Out of memory\n");
|
||||
return -1;
|
||||
|
@ -226,7 +226,7 @@ int flash_load(flash_file_t *ctx, const char *name, int can_write_bl)
|
|||
}
|
||||
num_phdrs = le16(ehdr.e_phnum);
|
||||
|
||||
phdrs = malloc(le16(ehdr.e_phnum) * sizeof(Elf32_Phdr));
|
||||
phdrs = calloc(le16(ehdr.e_phnum) * sizeof(Elf32_Phdr), sizeof(uint8_t));
|
||||
if (!phdrs) {
|
||||
fprintf(stderr, "Out of memory\n");
|
||||
goto fail;
|
||||
|
|
|
@ -224,7 +224,7 @@ void doMAC(uint8_t *cc_nr_p, uint8_t *div_key_p, uint8_t mac[4])
|
|||
{
|
||||
uint8_t cc_nr[13] = { 0 };
|
||||
uint8_t div_key[8];
|
||||
//cc_nr=(uint8_t*)malloc(length+1);
|
||||
//cc_nr=(uint8_t*) calloc(length+1, sizeof(uint8_t));
|
||||
|
||||
memcpy(cc_nr, cc_nr_p, 12);
|
||||
memcpy(div_key, div_key_p, 8);
|
||||
|
@ -244,7 +244,7 @@ void doMAC_N(uint8_t *address_data_p, uint8_t address_data_size, uint8_t *div_ke
|
|||
{
|
||||
uint8_t *address_data;
|
||||
uint8_t div_key[8];
|
||||
address_data = (uint8_t*) malloc(address_data_size);
|
||||
address_data = (uint8_t*) calloc(address_data_size, sizeof(uint8_t));
|
||||
|
||||
memcpy(address_data, address_data_p, address_data_size);
|
||||
memcpy(div_key, div_key_p, 8);
|
||||
|
|
|
@ -52,7 +52,7 @@ typedef struct {
|
|||
uint8_t * buffer;
|
||||
uint8_t numbits;
|
||||
uint8_t position;
|
||||
}BitstreamOut;
|
||||
} BitstreamOut;
|
||||
|
||||
bool headBit( BitstreamIn *stream);
|
||||
bool tailBit( BitstreamIn *stream);
|
||||
|
|
|
@ -493,7 +493,7 @@ int bruteforceDump(uint8_t dump[], size_t dumpsize, uint16_t keytable[]) {
|
|||
|
||||
uint64_t t1 = msclock();
|
||||
|
||||
dumpdata* attack = (dumpdata* ) malloc(itemsize);
|
||||
dumpdata* attack = (dumpdata* ) calloc(itemsize, sizeof(uint8_t));
|
||||
|
||||
for (i = 0 ; i * itemsize < dumpsize ; i++ ) {
|
||||
memcpy(attack, dump + i * itemsize, itemsize);
|
||||
|
|
|
@ -71,14 +71,14 @@ int saveFile(const char *preferredName, const char *suffix, const void* data, si
|
|||
/*Opening file for writing in binary mode*/
|
||||
FILE *f = fopen(fileName, "wb");
|
||||
if (!f) {
|
||||
PrintAndLogDevice(WARNING, "file not found or locked. '%s'", fileName);
|
||||
PrintAndLogDevice(WARNING, "file not found or locked. '" _YELLOW_(%s)"'", fileName);
|
||||
free(fileName);
|
||||
return 1;
|
||||
}
|
||||
fwrite(data, 1, datalen, f);
|
||||
fflush(f);
|
||||
fclose(f);
|
||||
PrintAndLogDevice(SUCCESS, "saved %u bytes to binary file %s", datalen, fileName);
|
||||
PrintAndLogDevice(SUCCESS, "saved %u bytes to binary file " _YELLOW_(%s), datalen, fileName);
|
||||
free(fileName);
|
||||
return 0;
|
||||
}
|
||||
|
@ -106,8 +106,8 @@ int saveFileEML(const char *preferredName, const char *suffix, uint8_t* data, si
|
|||
|
||||
/*Opening file for writing in text mode*/
|
||||
FILE *f = fopen(fileName, "w+");
|
||||
if (!f) {
|
||||
PrintAndLogDevice(WARNING, "file not found or locked. '%s'", fileName);
|
||||
if (!f) {
|
||||
PrintAndLogDevice(WARNING, "file not found or locked. '" _YELLOW_(%s)"'", fileName);
|
||||
retval = 1;
|
||||
goto out;
|
||||
}
|
||||
|
@ -130,7 +130,7 @@ int saveFileEML(const char *preferredName, const char *suffix, uint8_t* data, si
|
|||
}
|
||||
fflush(f);
|
||||
fclose(f);
|
||||
PrintAndLogDevice(SUCCESS, "saved %d blocks to text file %s", blocks, fileName);
|
||||
PrintAndLogDevice(SUCCESS, "saved %d blocks to text file " _YELLOW_(%s), blocks, fileName);
|
||||
|
||||
out:
|
||||
free(fileName);
|
||||
|
@ -240,13 +240,12 @@ int saveFileJSON(const char *preferredName, const char *suffix, JSONFileType fty
|
|||
|
||||
int res = json_dump_file(root, fileName, JSON_INDENT(2));
|
||||
if (res) {
|
||||
PrintAndLogDevice(FAILED, "error: can't save the file: %s", fileName);
|
||||
PrintAndLogDevice(FAILED, "error: can't save the file: " _YELLOW_(%s), fileName);
|
||||
json_decref(root);
|
||||
retval = 200;
|
||||
goto out;
|
||||
}
|
||||
PrintAndLogDevice(SUCCESS, "File `%s` saved.", fileName);
|
||||
|
||||
PrintAndLogDevice(SUCCESS, "saved to json file " _YELLOW_(%s), fileName);
|
||||
json_decref(root);
|
||||
|
||||
out:
|
||||
|
@ -266,7 +265,7 @@ int loadFile(const char *preferredName, const char *suffix, void* data, size_t*
|
|||
|
||||
FILE *f = fopen(fileName, "rb");
|
||||
if ( !f ) {
|
||||
PrintAndLogDevice(FAILED, "file: %s: not found or locked.", fileName);
|
||||
PrintAndLogDevice(WARNING, "file not found or locked. '" _YELLOW_(%s)"'", fileName);
|
||||
retval = 1;
|
||||
goto out;
|
||||
}
|
||||
|
@ -305,7 +304,7 @@ int loadFile(const char *preferredName, const char *suffix, void* data, size_t*
|
|||
memcpy( (data), dump, bytes_read);
|
||||
free(dump);
|
||||
|
||||
PrintAndLogDevice(SUCCESS, "loaded %d bytes from binary file %s", bytes_read, fileName);
|
||||
PrintAndLogDevice(SUCCESS, "loaded %d bytes from binary file " _YELLOW_(%s), bytes_read, fileName);
|
||||
|
||||
*datalen = bytes_read;
|
||||
|
||||
|
@ -328,7 +327,7 @@ int loadFileEML(const char *preferredName, const char *suffix, void* data, size_
|
|||
|
||||
FILE *f = fopen(fileName, "r");
|
||||
if ( !f ) {
|
||||
PrintAndLogDevice(FAILED, "file: %s: not found or locked.", fileName);
|
||||
PrintAndLogDevice(WARNING, "file not found or locked. '" _YELLOW_(%s)"'", fileName);
|
||||
retval = 1;
|
||||
goto out;
|
||||
}
|
||||
|
@ -359,7 +358,7 @@ int loadFileEML(const char *preferredName, const char *suffix, void* data, size_
|
|||
}
|
||||
}
|
||||
fclose(f);
|
||||
PrintAndLogDevice(SUCCESS, "loaded %d bytes from text file %s", counter, fileName);
|
||||
PrintAndLogDevice(SUCCESS, "loaded %d bytes from text file " _YELLOW_(%s), counter, fileName);
|
||||
*datalen = counter;
|
||||
|
||||
out:
|
||||
|
@ -382,13 +381,13 @@ int loadFileJSON(const char *preferredName, const char *suffix, void* data, size
|
|||
|
||||
root = json_load_file(fileName, 0, &error);
|
||||
if (!root) {
|
||||
PrintAndLog("ERROR: json (%s) error on line %d: %s", fileName, error.line, error.text);
|
||||
PrintAndLog("ERROR: json " _YELLOW_(%s) " error on line %d: %s", fileName, error.line, error.text);
|
||||
retval = 2;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!json_is_object(root)) {
|
||||
PrintAndLog("ERROR: Invalid json (%s) format. root must be an object.", fileName);
|
||||
PrintAndLog("ERROR: Invalid json " _YELLOW_(%s) " format. root must be an object.", fileName);
|
||||
retval = 3;
|
||||
goto out;
|
||||
}
|
||||
|
@ -446,7 +445,7 @@ int loadFileJSON(const char *preferredName, const char *suffix, void* data, size
|
|||
}
|
||||
|
||||
|
||||
PrintAndLog("Loaded JSON: (%s) OK.", fileName);
|
||||
PrintAndLog("loaded from JSON file " _YELLOW_(%s), fileName);
|
||||
out:
|
||||
json_decref(root);
|
||||
free(fileName);
|
||||
|
@ -479,7 +478,7 @@ int loadFileDICTIONARY(const char *preferredName, const char *suffix, void* data
|
|||
|
||||
FILE *f = fopen(fileName, "r");
|
||||
if ( !f ) {
|
||||
PrintAndLogDevice(FAILED, "file: %s: not found or locked.", fileName);
|
||||
PrintAndLogDevice(WARNING, "file not found or locked. '" _YELLOW_(%s)"'", fileName);
|
||||
retval = 1;
|
||||
goto out;
|
||||
}
|
||||
|
@ -512,7 +511,7 @@ int loadFileDICTIONARY(const char *preferredName, const char *suffix, void* data
|
|||
counter += (keylen >> 1);
|
||||
}
|
||||
fclose(f);
|
||||
PrintAndLogDevice(SUCCESS, "loaded " _GREEN_(%2d) "keys from dictionary file %s", *keycnt, fileName);
|
||||
PrintAndLogDevice(SUCCESS, "loaded " _GREEN_(%2d) "keys from dictionary file " _YELLOW_(%s), *keycnt, fileName);
|
||||
*datalen = counter;
|
||||
out:
|
||||
free(fileName);
|
||||
|
|
|
@ -1,72 +1,115 @@
|
|||
local manufacturer = {}
|
||||
manufacturer[0x01]='Motorola [UK]'
|
||||
manufacturer[0x02]='STMicroelectronics SA [France]'
|
||||
manufacturer[0x03]='Hitachi, Ltd [Japan]'
|
||||
manufacturer[0x04]='NXP Semiconductors [Germany]'
|
||||
manufacturer[0x05]='Infineon Technologies AG [Germany]'
|
||||
manufacturer[0x06]='Cylink [USA]'
|
||||
manufacturer[0x07]='Texas Instrument [France]'
|
||||
manufacturer[0x08]='Fujitsu Limited [Japan]'
|
||||
manufacturer[0x09]='Matsushita Electronics Corporation, Semiconductor Company [Japan]'
|
||||
manufacturer[0x0A]='NEC [Japan]'
|
||||
manufacturer[0x0B]='Oki Electric Industry Co. Ltd [Japan]'
|
||||
manufacturer[0x0C]='Toshiba Corp. [Japan]'
|
||||
manufacturer[0x0D]='Mitsubishi Electric Corp. [Japan]'
|
||||
manufacturer[0x0E]='Samsung Electronics Co. Ltd [Korea]'
|
||||
manufacturer[0x0F]='Hynix [Korea]'
|
||||
manufacturer[0x10]='LG-Semiconductors Co. Ltd [Korea]'
|
||||
manufacturer[0x11]='Emosyn-EM Microelectronics [USA]'
|
||||
manufacturer[0x12]='INSIDE Technology [France]'
|
||||
manufacturer[0x13]='ORGA Kartensysteme GmbH [Germany]'
|
||||
manufacturer[0x14]='SHARP Corporation [Japan]'
|
||||
manufacturer[0x15]='ATMEL [France]'
|
||||
manufacturer[0x16]='EM Microelectronic-Marin SA [Switzerland]'
|
||||
manufacturer[0x17]='KSW Microtec GmbH [Germany]'
|
||||
manufacturer[0x18]='ZMD AG [Germany]'
|
||||
manufacturer[0x19]='XICOR, Inc. [USA]'
|
||||
manufacturer[0x1A]='Sony Corporation [Japan]'
|
||||
manufacturer[0x1B]='Malaysia Microelectronic Solutions Sdn. Bhd [Malaysia]'
|
||||
manufacturer[0x1C]='Emosyn [USA]'
|
||||
manufacturer[0x1D]='Shanghai Fudan Microelectronics Co. Ltd. P.R. [China]'
|
||||
manufacturer[0x1E]='Magellan Technology Pty Limited [Australia]'
|
||||
manufacturer[0x1F]='Melexis NV BO [Switzerland]'
|
||||
manufacturer[0x20]='Renesas Technology Corp. [Japan]'
|
||||
manufacturer[0x21]='TAGSYS [France]'
|
||||
manufacturer[0x22]='Transcore [USA]'
|
||||
manufacturer[0x23]='Shanghai belling corp., ltd. [China]'
|
||||
manufacturer[0x24]='Masktech Germany Gmbh [Germany]'
|
||||
manufacturer[0x25]='Innovision Research and Technology Plc [UK]'
|
||||
manufacturer[0x26]='Hitachi ULSI Systems Co., Ltd. [Japan]'
|
||||
manufacturer[0x27]='Cypak AB [Sweden]'
|
||||
manufacturer[0x28]='Ricoh [Japan]'
|
||||
manufacturer[0x29]='ASK [France]'
|
||||
manufacturer[0x2A]='Unicore Microsystems, LLC [RussianFederation]'
|
||||
manufacturer[0x2B]='Dallas Semiconductor/Maxim [USA]'
|
||||
manufacturer[0x2C]='Impinj, Inc. [USA]'
|
||||
manufacturer[0x2D]='RightPlug Alliance [USA]'
|
||||
manufacturer[0x2E]='Broadcom Corporation [USA]'
|
||||
manufacturer[0x2F]='MStar Semiconductor, Inc Taiwan, [ROC]'
|
||||
manufacturer[0x30]='BeeDar Technology Inc. [USA]'
|
||||
manufacturer[0x31]='RFIDsec [Denmark]'
|
||||
manufacturer[0x32]='Schweizer Electronic AG [Germany]'
|
||||
manufacturer[0x33]='AMIC Technology Corp [Taiwan]'
|
||||
manufacturer[0x34]='Mikron JSC [Russia]'
|
||||
manufacturer[0x35]='Fraunhofer Institute for Photonic Microsystems [Germany]'
|
||||
manufacturer[0x36]='IDS Microchip AG [Switzerland]'
|
||||
manufacturer[0x37]='Kovio [USA]'
|
||||
manufacturer[0x38]='HMT Microelectronic Ltd [Switzerland]'
|
||||
manufacturer[0x39]='Silicon Craft Technology [Thailand]'
|
||||
manufacturer[0x3A]='Advanced Film Device Inc. [Japan]'
|
||||
manufacturer[0x3B]='Nitecrest Ltd [UK]'
|
||||
manufacturer[0x3C]='Verayo Inc. [USA]'
|
||||
manufacturer[0x3D]='HID Global [USA]'
|
||||
manufacturer[0x3E]='Productivity Engineering Gmbh [Germany]'
|
||||
manufacturer[0x3F]='Austriamicrosystems AG (reserved) [Austria]'
|
||||
manufacturer[0x40]='Gemalto SA [France]'
|
||||
manufacturer[0x41]='Renesas Electronics Corporation [Japan]'
|
||||
manufacturer[0x42]='3Alogics Inc [Korea]'
|
||||
manufacturer[0x43]='Top TroniQ Asia Limited Hong [Kong]'
|
||||
manufacturer[0x44]='Gentag Inc (USA) [USA]'
|
||||
local m = {}
|
||||
m[0x01]='Motorola UK'
|
||||
m[0x02]='ST Microelectronics SA France'
|
||||
m[0x03]='Hitachi, Ltd Japan'
|
||||
m[0x04]='NXP Semiconductors Germany'
|
||||
m[0x05]='Infineon Technologies AG Germany'
|
||||
m[0x06]='Cylink USA'
|
||||
m[0x07]='Texas Instrument France'
|
||||
m[0x08]='Fujitsu Limited Japan'
|
||||
m[0x09]='Matsushita Electronics Corporation, Semiconductor Company Japan'
|
||||
m[0x0A]='NEC Japan'
|
||||
m[0x0B]='Oki Electric Industry Co. Ltd Japan'
|
||||
m[0x0C]='Toshiba Corp. Japan'
|
||||
m[0x0D]='Mitsubishi Electric Corp. Japan'
|
||||
m[0x0E]='Samsung Electronics Co. Ltd Korea'
|
||||
m[0x0F]='Hynix / Hyundai, Korea'
|
||||
m[0x10]='LG-Semiconductors Co. Ltd Korea'
|
||||
m[0x11]='Emosyn-EM Microelectronics USA'
|
||||
m[0x12]='INSIDE Technology France'
|
||||
m[0x13]='ORGA Kartensysteme GmbH Germany'
|
||||
m[0x14]='SHARP Corporation Japan'
|
||||
m[0x15]='ATMEL France'
|
||||
m[0x16]='EM Microelectronic-Marin SA Switzerland'
|
||||
m[0x17]='KSW Microtec GmbH Germany'
|
||||
m[0x18]='ZMD AG Germany'
|
||||
m[0x19]='XICOR, Inc. USA'
|
||||
m[0x1A]='Sony Corporation Japan'
|
||||
m[0x1B]='Malaysia Microelectronic Solutions Sdn. Bhd Malaysia'
|
||||
m[0x1C]='Emosyn USA'
|
||||
m[0x1D]='Shanghai Fudan Microelectronics Co. Ltd. P.R. China'
|
||||
m[0x1E]='Magellan Technology Pty Limited Australia'
|
||||
m[0x1F]='Melexis NV BO Switzerland'
|
||||
m[0x20]='Renesas Technology Corp. Japan'
|
||||
m[0x21]='TAGSYS France'
|
||||
m[0x22]='Transcore USA'
|
||||
m[0x23]='Shanghai belling corp., ltd. China'
|
||||
m[0x24]='Masktech Germany Gmbh Germany'
|
||||
m[0x25]='Innovision Research and Technology Plc UK'
|
||||
m[0x26]='Hitachi ULSI Systems Co., Ltd. Japan'
|
||||
m[0x27]='Cypak AB Sweden'
|
||||
m[0x28]='Ricoh Japan'
|
||||
m[0x29]='ASK France'
|
||||
m[0x2A]='Unicore Microsystems, LLC RussianFederation'
|
||||
m[0x2B]='Dallas Semiconductor/Maxim USA'
|
||||
m[0x2C]='Impinj, Inc. USA'
|
||||
m[0x2D]='RightPlug Alliance USA'
|
||||
m[0x2E]='Broadcom Corporation USA'
|
||||
m[0x2F]='MStar Semiconductor, Inc Taiwan, ROC'
|
||||
m[0x30]='BeeDar Technology Inc. USA'
|
||||
m[0x31]='RFIDsec Denmark'
|
||||
m[0x32]='Schweizer Electronic AG Germany'
|
||||
m[0x33]='AMIC Technology Corp Taiwan'
|
||||
m[0x34]='Mikron JSC Russia'
|
||||
m[0x35]='Fraunhofer Institute for Photonic Microsystems Germany'
|
||||
m[0x36]='IDS Microchip AG Switzerland'
|
||||
m[0x37]='Kovio USA'
|
||||
m[0x38]='HMT Microelectronic Ltd Switzerland'
|
||||
m[0x39]='Silicon Craft Technology Thailand'
|
||||
m[0x3A]='Advanced Film Device Inc. Japan'
|
||||
m[0x3B]='Nitecrest Ltd UK'
|
||||
m[0x3C]='Verayo Inc. USA'
|
||||
m[0x3D]='HID Global USA'
|
||||
m[0x3E]='Productivity Engineering Gmbh Germany'
|
||||
m[0x3F]='Austriamicrosystems AG (reserved) Austria'
|
||||
m[0x40]='Gemalto SA France'
|
||||
m[0x41]='Renesas Electronics Corporation Japan'
|
||||
m[0x42]='3Alogics Inc Korea'
|
||||
m[0x43]='Top TroniQ Asia Limited Hong Kong'
|
||||
m[0x44]='Gentag Inc USA'
|
||||
m[0x45]='Invengo Information Technology Co.Ltd China'
|
||||
m[0x46]='Guangzhou Sysur Microelectronics, Inc China'
|
||||
m[0x47]='CEITEC S.A. Brazil'
|
||||
m[0x48]='Shanghai Quanray Electronics Co. Ltd. China'
|
||||
m[0x49]='MediaTek Inc Taiwan'
|
||||
m[0x4A]='Angstrem PJSC Russia'
|
||||
m[0x4B]='Celisic Semiconductor (Hong Kong) Limited China'
|
||||
m[0x4C]='LEGIC Identsystems AG Switzerland'
|
||||
m[0x4D]='Balluff GmbH Germany'
|
||||
m[0x4E]='Oberthur Technologies France'
|
||||
m[0x4F]='Silterra Malaysia Sdn. Bhd. Malaysia'
|
||||
m[0x50]='DELTA Danish Electronics, Light & Acoustics Denmark'
|
||||
m[0x51]='Giesecke & Devrient GmbH Germany'
|
||||
m[0x52]='Shenzhen China Vision Microelectronics Co., Ltd. China'
|
||||
m[0x53]='Shanghai Feiju Microelectronics Co. Ltd. China'
|
||||
m[0x54]='Intel Corporation USA'
|
||||
m[0x55]='Microsensys GmbH Germany'
|
||||
m[0x56]='Sonix Technology Co., Ltd. Taiwan'
|
||||
m[0x57]='Qualcomm Technologies Inc USA'
|
||||
m[0x58]='Realtek Semiconductor Corp Taiwan'
|
||||
m[0x59]='Freevision Technologies Co. Ltd China'
|
||||
m[0x5A]='Giantec Semiconductor Inc. China'
|
||||
m[0x5B]='JSC Angstrem-T Russia'
|
||||
m[0x5C]='STARCHIP France'
|
||||
m[0x5D]='SPIRTECH France'
|
||||
m[0x5E]='GANTNER Electronic GmbH Austria'
|
||||
m[0x5F]='Nordic Semiconductor Norway'
|
||||
m[0x60]='Verisiti Inc USA'
|
||||
m[0x61]='Wearlinks Technology Inc. China'
|
||||
m[0x62]='Userstar Information Systems Co., Ltd Taiwan'
|
||||
m[0x63]='Pragmatic Printing Ltd. UK'
|
||||
m[0x64]='Associacao do Laboratorio de Sistemas Integraveis Tecnologico – LSI-TEC Brazil'
|
||||
m[0x65]='Tendyron Corporation China'
|
||||
m[0x66]='MUTO Smart Co., Ltd. Korea'
|
||||
m[0x67]='ON Semiconductor USA'
|
||||
m[0x68]='TUBITAK BILGEM Turkey'
|
||||
m[0x69]='Huada Semiconductor Co., Ltd China'
|
||||
m[0x6A]='SEVENEY France'
|
||||
m[0x6B]='ISSM France'
|
||||
m[0x6C]='Wisesec Ltd Israel'
|
||||
m[0x7C]='DB HiTek Co Ltd Korea'
|
||||
m[0x7D]='SATO Vicinity Australia'
|
||||
m[0x7E]='Holtek Taiwan'
|
||||
|
||||
return {
|
||||
lookupManufacturer = function (value)
|
||||
|
@ -76,8 +119,6 @@ return {
|
|||
value = v
|
||||
end
|
||||
|
||||
return manufacturer[value] or "no tag-info available"
|
||||
return m[value] or "no tag-info available"
|
||||
end,
|
||||
|
||||
|
||||
}
|
|
@ -173,18 +173,19 @@ int mfCheckKeys_fast( uint8_t sectorsCnt, uint8_t firstChunk, uint8_t lastChunk,
|
|||
|
||||
// success array. each byte is status of key
|
||||
uint8_t arr[80];
|
||||
uint64_t foo = bytes_to_num(resp.d.asBytes+480, 8);
|
||||
for (uint8_t i = 0; i < 64; ++i) {
|
||||
arr[i] = (foo >> i) & 0x1;
|
||||
}
|
||||
foo = bytes_to_num(resp.d.asBytes+488, 2);
|
||||
for (uint8_t i = 0; i < 16; ++i) {
|
||||
arr[i+64] = (foo >> i) & 0x1;
|
||||
}
|
||||
uint64_t foo = 0;
|
||||
uint16_t bar = 0;
|
||||
foo = bytes_to_num(resp.d.asBytes+480, 8);
|
||||
bar = (resp.d.asBytes[489] << 8 | resp.d.asBytes[488]);
|
||||
|
||||
for (uint8_t i = 0; i < 64; i++)
|
||||
arr[i] = (foo >> i) & 0x1;
|
||||
|
||||
for (uint8_t i = 0; i < 16; i++)
|
||||
arr[i+64] = (bar >> i) & 0x1;
|
||||
|
||||
// initialize storage for found keys
|
||||
icesector_t *tmp = NULL;
|
||||
tmp = calloc(sectorsCnt, sizeof(icesector_t));
|
||||
icesector_t *tmp = calloc(sectorsCnt, sizeof(icesector_t));
|
||||
if (tmp == NULL)
|
||||
return 1;
|
||||
memcpy(tmp, resp.d.asBytes, sectorsCnt * sizeof(icesector_t) );
|
||||
|
|
|
@ -215,11 +215,11 @@ const char *get_my_executable_directory(void) {
|
|||
static void set_my_executable_path(void) {
|
||||
int path_length = wai_getExecutablePath(NULL, 0, NULL);
|
||||
if (path_length != -1) {
|
||||
my_executable_path = (char*)malloc(path_length + 1);
|
||||
my_executable_path = (char*)calloc(path_length + 1, sizeof(uint8_t));
|
||||
int dirname_length = 0;
|
||||
if (wai_getExecutablePath(my_executable_path, path_length, &dirname_length) != -1) {
|
||||
my_executable_path[path_length] = '\0';
|
||||
my_executable_directory = (char *)malloc(dirname_length + 2);
|
||||
my_executable_directory = (char *)calloc(dirname_length + 2, sizeof(uint8_t));
|
||||
strncpy(my_executable_directory, my_executable_path, dirname_length+1);
|
||||
my_executable_directory[dirname_length+1] = '\0';
|
||||
}
|
||||
|
@ -321,9 +321,9 @@ int main(int argc, char* argv[]) {
|
|||
} else {
|
||||
if (addLuaExec){
|
||||
// add "script run " to command
|
||||
char *ctmp = NULL;
|
||||
int len = strlen(script_cmd) + 11 + 1;
|
||||
if ((ctmp = (char*) malloc(len)) != NULL) {
|
||||
char *ctmp = (char*) calloc(len, sizeof(uint8_t));
|
||||
if (ctmp != NULL) {
|
||||
memset(ctmp, 0, len);
|
||||
strcpy(ctmp, "script run ");
|
||||
strcpy(&ctmp[11], script_cmd);
|
||||
|
|
|
@ -377,7 +377,9 @@ ipqx:
|
|||
|
||||
/* allocate argument array */
|
||||
args = argc - optind;
|
||||
if(!(apolys = malloc(args * sizeof(poly_t)))){
|
||||
|
||||
apolys = calloc(args * sizeof(poly_t), sizeof(char));
|
||||
if ( !apolys ){
|
||||
uerror("cannot allocate memory for argument list");
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -118,7 +118,7 @@ char * mtostr(const model_t *model) {
|
|||
+ (checkstr && *checkstr ? strlen(checkstr) : 6)
|
||||
+ (magicstr && *magicstr ? strlen(magicstr) : 6)
|
||||
+ (model->name && *model->name ? 2 + strlen(model->name) : 6);
|
||||
if ((string = malloc(size))) {
|
||||
if ((string = calloc(size, sizeof(uint8_t)))) {
|
||||
sprintf(strbuf, "\"%s\"", model->name);
|
||||
sprintf(string,
|
||||
"width=%lu "
|
||||
|
|
|
@ -349,7 +349,7 @@ pxsubs(const poly_t poly, int flags, int bperhx, unsigned long start, unsigned l
|
|||
size *= cperhx;
|
||||
if(!size || ~flags & P_SPACE) ++size; /* for trailing null */
|
||||
|
||||
if(!(sptr = string = (char *) malloc(size)))
|
||||
if(!(sptr = string = (char *) calloc(size, sizeof(char))))
|
||||
uerror("cannot allocate memory for string");
|
||||
|
||||
size = end - start;
|
||||
|
|
|
@ -811,7 +811,9 @@ int mbynam(model_t *dest, const char *key) {
|
|||
|
||||
if (!aliases->name)
|
||||
return(-1);
|
||||
if (!(ukey = malloc((size_t) 1 + strlen(key) + 1))) {
|
||||
|
||||
ukey = calloc((size_t) 1 + strlen(key) + 1, sizeof(char));
|
||||
if (!ukey) {
|
||||
uerror("[!] cannot allocate memory for comparison string");
|
||||
return(0);
|
||||
}
|
||||
|
@ -861,7 +863,9 @@ char * mnames(void) {
|
|||
++aptr;
|
||||
}
|
||||
if (!size) return(NULL);
|
||||
if ((string = malloc(size))) {
|
||||
|
||||
string = calloc(size, sizeof(char));
|
||||
if (string) {
|
||||
aptr = aliases;
|
||||
sptr = string;
|
||||
while (aptr->name) {
|
||||
|
|
|
@ -173,8 +173,9 @@ modpol(const poly_t init, int rflags, int args, const poly_t *argpolys) {
|
|||
unsigned long alen, blen;
|
||||
|
||||
if(args < 2) return(NULL);
|
||||
|
||||
if(!(result = malloc(((((args - 1) * args) >> 1) + 1) * sizeof(poly_t))))
|
||||
|
||||
result = calloc(((((args - 1) * args) >> 1) + 1) * sizeof(poly_t), sizeof(char));
|
||||
if(!result)
|
||||
uerror("cannot allocate memory for codeword table");
|
||||
|
||||
rptr = result;
|
||||
|
@ -240,7 +241,8 @@ engini(int *resc, model_t **result, const poly_t divisor, int flags, int args, c
|
|||
dlen = plen(divisor);
|
||||
|
||||
/* Allocate the CRC matrix */
|
||||
if(!(mat = (poly_t *) malloc((dlen << 1) * sizeof(poly_t))))
|
||||
mat = (poly_t *) calloc((dlen << 1) * sizeof(poly_t), sizeof(char));
|
||||
if(!mat)
|
||||
uerror("cannot allocate memory for CRC matrix");
|
||||
|
||||
/* Find arguments of the two shortest lengths */
|
||||
|
|
|
@ -51,7 +51,8 @@ int scandir (const char *dir,
|
|||
nl = ntmp;
|
||||
}
|
||||
|
||||
if (!(etmp = (struct dirent *) malloc (sizeof *ent))) {
|
||||
etmp = (struct dirent *) calloc (sizeof *ent, sizeof(char));
|
||||
if (!etmp) {
|
||||
err_no = 1;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -758,6 +758,15 @@ int set_pm3_libraries(lua_State *L) {
|
|||
//-- remove the global environment table from the stack
|
||||
lua_pop(L, 1);
|
||||
|
||||
|
||||
//--add to the LUA_PATH (package.path in lua)
|
||||
// so we can load scripts from the ./scripts/ - directory
|
||||
char scripts_path[strlen(get_my_executable_directory()) + strlen(LUA_SCRIPTS_DIRECTORY) + strlen(LUA_LIBRARIES_WILDCARD) + 1];
|
||||
strcpy(scripts_path, get_my_executable_directory());
|
||||
strcat(scripts_path, LUA_SCRIPTS_DIRECTORY);
|
||||
strcat(scripts_path, LUA_LIBRARIES_WILDCARD);
|
||||
setLuaPath(L, scripts_path);
|
||||
|
||||
//-- Last but not least, add to the LUA_PATH (package.path in lua)
|
||||
// so we can load libraries from the ./lualib/ - directory
|
||||
char libraries_path[strlen(get_my_executable_directory()) + strlen(LUA_LIBRARIES_DIRECTORY) + strlen(LUA_LIBRARIES_WILDCARD) + 1];
|
||||
|
@ -765,6 +774,5 @@ int set_pm3_libraries(lua_State *L) {
|
|||
strcat(libraries_path, LUA_LIBRARIES_DIRECTORY);
|
||||
strcat(libraries_path, LUA_LIBRARIES_WILDCARD);
|
||||
setLuaPath(L, libraries_path);
|
||||
|
||||
return 1;
|
||||
}
|
|
@ -5,7 +5,7 @@ local utils = require('utils')
|
|||
|
||||
copyright = 'Copyright (c) 2018 IceSQL AB. All rights reserved.'
|
||||
author = 'Christian Herrmann'
|
||||
version = 'v1.0.3'
|
||||
version = 'v1.0.4'
|
||||
desc = [[
|
||||
This script tries to set UID on a IS15693 SLIX magic card
|
||||
Remember the UID ->MUST<- start with 0xE0
|
||||
|
@ -15,6 +15,8 @@ example = [[
|
|||
-- ISO15693 slix magic tag
|
||||
|
||||
script run iso15_magic -u E004013344556677
|
||||
|
||||
script run iso15_magic -u E004013344556677 -a
|
||||
]]
|
||||
usage = [[
|
||||
script run iso15_magic -h -u <uid>
|
||||
|
@ -22,6 +24,7 @@ script run iso15_magic -h -u <uid>
|
|||
Arguments:
|
||||
-h : this help
|
||||
-u <UID> : UID (16 hexsymbols)
|
||||
-a : use offical pm3 repo ISO15 commands instead of iceman fork.
|
||||
]]
|
||||
|
||||
local DEBUG = true
|
||||
|
@ -82,11 +85,13 @@ function main(args)
|
|||
print()
|
||||
|
||||
local uid = 'E004013344556677'
|
||||
local use_iceman = true
|
||||
|
||||
-- Read the parameters
|
||||
for o, a in getopt.getopt(args, 'hu:') do
|
||||
for o, a in getopt.getopt(args, 'hu:a') do
|
||||
if o == "h" then return help() end
|
||||
if o == "u" then uid = a end
|
||||
if o == "a" then use_iceman = false end
|
||||
end
|
||||
|
||||
-- uid string checks
|
||||
|
@ -103,8 +108,11 @@ function main(args)
|
|||
|
||||
core.clearCommandBuffer()
|
||||
|
||||
magicUID_iceman(block0, block1)
|
||||
--magicUID_offical(block0, block1)
|
||||
if use_iceman then
|
||||
magicUID_iceman(block0, block1)
|
||||
else
|
||||
magicUID_offical(block0, block1)
|
||||
end
|
||||
end
|
||||
|
||||
main(args)
|
||||
|
|
|
@ -513,8 +513,8 @@ function readFromPM3()
|
|||
return tag
|
||||
end
|
||||
|
||||
function padString(str)
|
||||
if (str:len() == 1) then
|
||||
local function padString(str)
|
||||
if (#str == 1) then
|
||||
return '0'..str
|
||||
end
|
||||
|
||||
|
@ -524,73 +524,84 @@ end
|
|||
---
|
||||
-- write virtual Tag to real Tag
|
||||
function writeToTag(tag)
|
||||
local bytes
|
||||
local filename='MylegicClone.hex'
|
||||
local taglen=22
|
||||
local bytes
|
||||
local filename = 'MylegicClone.hex'
|
||||
local taglen = 22
|
||||
if(utils.confirm(acred.."\nplace the (empty) Tag onto the PM3\nand confirm writing to this Tag: "..acoff) == false) then
|
||||
return
|
||||
end
|
||||
-- get used bytes / tag-len
|
||||
if(istable(tag.SEG)) then
|
||||
if (istable(tag.Bck)) then
|
||||
for i=0, #tag.SEG do
|
||||
taglen=taglen+tag.SEG[i].len+5
|
||||
end
|
||||
end
|
||||
local uid_old=tag.MCD..tag.MSN0..tag.MSN1..tag.MSN2
|
||||
-- read new tag into memory so we can xor the new data with the new MCC
|
||||
outTAG=readFromPM3()
|
||||
outbytes=tagToBytes(outTAG)
|
||||
-- copy 'inputbuffer' to 'outputbuffer'
|
||||
tag.MCD = outbytes[1]
|
||||
tag.MSN0 = outbytes[2]
|
||||
tag.MSN1 = outbytes[3]
|
||||
tag.MSN2 = outbytes[4]
|
||||
tag.MCC = outbytes[5]
|
||||
-- recheck all segments-crc/kghcrc (only on a credential)
|
||||
if(istable(tag.Bck)) then
|
||||
checkAllSegCrc(tag)
|
||||
checkAllKghCrc(tag)
|
||||
local uid_new=tag.MCD..tag.MSN0..tag.MSN1..tag.MSN2
|
||||
for i=0, #tag.SEG do
|
||||
if (check43rdPartyCash1(uid_old, tag.SEG[i].data)) then
|
||||
io.write(accyan.."\nfixing known checksums"..acoff.." ... ")
|
||||
if (fix3rdPartyCash1(uid_new, tag.SEG[i].data)) then
|
||||
io.write(acgreen.." done\n"..acoff)
|
||||
else oops("\nsomething went wrong at the repair of the 3rd-party-cash-segment") end
|
||||
end
|
||||
end
|
||||
end
|
||||
bytes=tagToBytes(tag)
|
||||
-- master-token-crc
|
||||
if (tag.Type ~= "SAM") then bytes[22] = calcMtCrc(bytes) end
|
||||
if (bytes) then
|
||||
print("write temp-file '"..filename.."'")
|
||||
print(accyan)
|
||||
writeFile(bytes, filename..".bin")
|
||||
print(acoff)
|
||||
end
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
-- get used bytes / tag-len
|
||||
if (istable(tag.SEG)) then
|
||||
if (istable(tag.Bck)) then
|
||||
for i=0, #tag.SEG do
|
||||
taglen = taglen + tag.SEG[i] . len + 5
|
||||
end
|
||||
end
|
||||
local uid_old = tag.MCD..tag.MSN0..tag.MSN1..tag.MSN2
|
||||
|
||||
-- read new tag into memory so we can xor the new data with the new MCC
|
||||
outTAG = readFromPM3()
|
||||
outbytes = tagToBytes(outTAG)
|
||||
-- copy 'inputbuffer' to 'outputbuffer'
|
||||
tag.MCD = outbytes[1]
|
||||
tag.MSN0 = outbytes[2]
|
||||
tag.MSN1 = outbytes[3]
|
||||
tag.MSN2 = outbytes[4]
|
||||
tag.MCC = outbytes[5]
|
||||
-- recheck all segments-crc/kghcrc (only on a credential)
|
||||
if (istable(tag.Bck)) then
|
||||
checkAllSegCrc(tag)
|
||||
checkAllKghCrc(tag)
|
||||
local uid_new = tag.MCD..tag.MSN0..tag.MSN1..tag.MSN2
|
||||
for i=0, #tag.SEG do
|
||||
if (check43rdPartyCash1(uid_old, tag.SEG[i].data)) then
|
||||
io.write(accyan.."\nfixing known checksums"..acoff.." ... ")
|
||||
if (fix3rdPartyCash1(uid_new, tag.SEG[i].data)) then
|
||||
io.write(acgreen.." done\n"..acoff)
|
||||
else
|
||||
oops("\nsomething went wrong at the repair of the 3rd-party-cash-segment")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
bytes = tagToBytes(tag)
|
||||
-- master-token-crc
|
||||
if (tag.Type ~= "SAM") then
|
||||
bytes[22] = calcMtCrc(bytes)
|
||||
end
|
||||
if (bytes) then
|
||||
print("write temp-file '"..filename.."'")
|
||||
print(accyan)
|
||||
writeFile(bytes, filename..".bin")
|
||||
print(acoff)
|
||||
end
|
||||
end
|
||||
|
||||
-- write data to file
|
||||
-- write data to file
|
||||
if (taglen > 0) then
|
||||
WriteBytes = utils.input(acyellow.."enter number of bytes to write?"..acoff, taglen)
|
||||
-- load file into pm3-buffer
|
||||
if (type(filename) ~= "string") then filename=input(acyellow.."filename to load to pm3-buffer?"..acoff,"legic.temp") end
|
||||
if (type(filename) ~= "string") then
|
||||
filename = input(acyellow.."filename to load to pm3-buffer?"..acoff, "legic.temp")
|
||||
end
|
||||
|
||||
cmd = 'hf legic eload 2 '..filename
|
||||
core.console(cmd)
|
||||
-- write pm3-buffer to Tag
|
||||
for i=0, WriteBytes do
|
||||
if (i > 6) then
|
||||
cmd = 'hf legic write o '..string.format("%x", i)..' d '..padString(bytes[i])
|
||||
print(acgreen..cmd..acoff)
|
||||
cmd = ("hf legic write o %x d %s "):format(i, padString(bytes[i]))
|
||||
print(acgreen..cmd..acoff)
|
||||
core.console(cmd)
|
||||
core.clearCommandBuffer()
|
||||
elseif (i == 6) then
|
||||
-- write DCF in reverse order (requires 'mosci-patch')
|
||||
cmd = 'hf legic write o 05 d '..padString(bytes[i-1])..padString(bytes[i])
|
||||
print(acgreen..cmd..acoff)
|
||||
-- write DCF in reverse order (requires 'mosci-patch')
|
||||
cmd = ('hf legic write o 05 d %s%s'):format(padString(bytes[i-1]), padString(bytes[i]))
|
||||
print(acgreen..cmd..acoff)
|
||||
core.console(cmd)
|
||||
elseif (i == 5) then
|
||||
core.clearCommandBuffer()
|
||||
elseif (i == 5) then
|
||||
print(acgreen.."skip byte 0x05 - will be written next step"..acoff)
|
||||
else
|
||||
print(acgreen.."skip byte 0x00-0x04 - unwritable area"..acoff)
|
||||
|
@ -603,26 +614,28 @@ end
|
|||
--- File I/O ---
|
||||
---
|
||||
-- read file into virtual-tag
|
||||
function readFile(filename)
|
||||
print(accyan)
|
||||
local bytes = {}
|
||||
local tag = {}
|
||||
if file_check(filename) == false then return oops("input file: "..filename.." not found") end
|
||||
local function readFile(filename)
|
||||
print(accyan)
|
||||
local bytes = {}
|
||||
local tag = {}
|
||||
if file_check(filename) == false then
|
||||
return oops("input file: "..filename.." not found")
|
||||
end
|
||||
|
||||
bytes = getInputBytes(filename)
|
||||
bytes = getInputBytes(filename)
|
||||
|
||||
if bytes == false then return oops('couldnt get input bytes') end
|
||||
if bytes == false then return oops('couldnt get input bytes') end
|
||||
|
||||
-- make plain bytes
|
||||
bytes = xorBytes(bytes,bytes[5])
|
||||
print("create virtual tag from ".. #bytes .. " bytes")
|
||||
-- create Tag for plain bytes
|
||||
tag=createTagTable()
|
||||
-- load plain bytes to tag-table
|
||||
print(acoff)
|
||||
tag=bytesToTag(bytes, tag)
|
||||
-- make plain bytes
|
||||
bytes = xorBytes(bytes,bytes[5])
|
||||
print("create virtual tag from ".. #bytes .. " bytes")
|
||||
-- create Tag for plain bytes
|
||||
tag = createTagTable()
|
||||
-- load plain bytes to tag-table
|
||||
print(acoff)
|
||||
tag = bytesToTag(bytes, tag)
|
||||
|
||||
return tag
|
||||
return tag
|
||||
end
|
||||
|
||||
---
|
||||
|
@ -631,14 +644,16 @@ function writeFile(bytes, filename)
|
|||
if (filename ~= 'MylegicClone.hex') then
|
||||
if (file_check(filename)) then
|
||||
local answer = confirm("\nthe output-file "..filename.." already exists!\nthis will delete the previous content!\ncontinue?")
|
||||
if (answer==false) then return print("user abort") end
|
||||
if not answer then return print("user abort") end
|
||||
end
|
||||
end
|
||||
local line
|
||||
local bcnt=0
|
||||
local fho,err = io.open(filename, "w")
|
||||
if err then oops("OOps ... failed to open output-file ".. filename) end
|
||||
bytes=xorBytes(bytes, bytes[5])
|
||||
local bcnt = 0
|
||||
local fho, err = io.open(filename, "w")
|
||||
if err then
|
||||
return oops("OOps ... failed to open output-file ".. filename)
|
||||
end
|
||||
bytes = xorBytes(bytes, bytes[5])
|
||||
for i = 1, #bytes do
|
||||
if (bcnt == 0) then
|
||||
line = bytes[i]
|
||||
|
@ -662,96 +677,96 @@ end
|
|||
--- Map related ---
|
||||
---
|
||||
-- make tagMap
|
||||
function makeTagMap()
|
||||
local tagMap={}
|
||||
if (#tagMap == 0) then
|
||||
tagMap['name'] = input(accyan.."enter Name for this Map: "..acoff , "newTagMap")
|
||||
tagMap['mappings']={}
|
||||
tagMap['crc8']={}
|
||||
-- insert fixed Tag-CRC
|
||||
table.insert(tagMap.crc8, {name='TAG-CRC', pos=5, seq={1, 4}})
|
||||
tagMap['crc16']={}
|
||||
end
|
||||
print(accyan.."new tagMap created"..acoff)
|
||||
return tagMap
|
||||
local function makeTagMap()
|
||||
local tagMap = {}
|
||||
if (#tagMap == 0) then
|
||||
tagMap['name'] = input(accyan.."enter Name for this Map: "..acoff , "newTagMap")
|
||||
tagMap['mappings'] = {}
|
||||
tagMap['crc8'] = {}
|
||||
-- insert fixed Tag-CRC
|
||||
table.insert(tagMap.crc8, {name = 'TAG-CRC', pos = 5, seq = {1, 4}})
|
||||
tagMap['crc16'] = {}
|
||||
end
|
||||
print(accyan.."new tagMap created"..acoff)
|
||||
return tagMap
|
||||
end
|
||||
|
||||
---
|
||||
-- save mapping to file
|
||||
function saveTagMap(map, filename)
|
||||
if (string.len(filename)>0) then
|
||||
if (file_check(filename)) then
|
||||
local answer = confirm("\nthe output-file "..filename.." alredy exists!\nthis will delete the previous content!\ncontinue?")
|
||||
if (answer==false) then return print("user abort") end
|
||||
end
|
||||
end
|
||||
local function saveTagMap(map, filename)
|
||||
if (string.len(filename)>0) then
|
||||
if (file_check(filename)) then
|
||||
local answer = confirm("\nthe output-file "..filename.." alredy exists!\nthis will delete the previous content!\ncontinue?")
|
||||
if not answer then return print("user abort") end
|
||||
end
|
||||
end
|
||||
|
||||
local line
|
||||
local line
|
||||
local fho,err = io.open(filename, "w")
|
||||
if err then oops("OOps ... faild to open output-file ".. filename) end
|
||||
|
||||
-- write line to new file
|
||||
for k, v in pairs(map) do
|
||||
if (istable(v)) then
|
||||
for k2, v2 in pairs(v) do
|
||||
if (k=='mappings') then
|
||||
fho:write(k..","..k2..","..v2['name']..","..v2['start']..","..v2['end']..","..((v2['highlight']) and "1" or "0").."\n")
|
||||
elseif (k=="crc8") then
|
||||
local tmp=""
|
||||
tmp=k..","..k2..","..v2['name']..","..v2['pos']..","
|
||||
tmp=tmp..tbl2seqstr(v2['seq'])
|
||||
fho:write(tmp.."\n")
|
||||
end
|
||||
end
|
||||
else
|
||||
fho:write(k..","..v.."\n")
|
||||
end
|
||||
end
|
||||
-- write line to new file
|
||||
for k, v in pairs(map) do
|
||||
if (istable(v)) then
|
||||
for k2, v2 in pairs(v) do
|
||||
if (k == 'mappings') then
|
||||
fho:write(k..","..k2..","..v2['name']..","..v2['start']..","..v2['end']..","..((v2['highlight']) and "1" or "0").."\n")
|
||||
elseif (k == "crc8") then
|
||||
local tmp = ""
|
||||
tmp = k..","..k2..","..v2['name']..","..v2['pos']..","
|
||||
tmp=tmp..tbl2seqstr(v2['seq'])
|
||||
fho:write(tmp.."\n")
|
||||
end
|
||||
end
|
||||
else
|
||||
fho:write(k..","..v.."\n")
|
||||
end
|
||||
end
|
||||
fho:close()
|
||||
return true
|
||||
end
|
||||
|
||||
---
|
||||
-- toggle higligh
|
||||
function toggleHighlight(tbl)
|
||||
local function toggleHighlight(tbl)
|
||||
if (tbl['highlight']) then
|
||||
tbl['highlight'] = false
|
||||
else
|
||||
tbl['highlight'] = true
|
||||
end
|
||||
return tbl
|
||||
return tbl
|
||||
end
|
||||
|
||||
---
|
||||
-- return table od seqence-string
|
||||
function seqstr2tbl(seqstr)
|
||||
local s=split(seqstr)
|
||||
local res={}
|
||||
if (#s>=1) then
|
||||
for sk, sv in pairs(s) do
|
||||
s2=split(sv, '-')
|
||||
if(#s2==2) then
|
||||
table.insert(res, s2[1])
|
||||
table.insert(res, s2[2])
|
||||
end
|
||||
end
|
||||
end
|
||||
return res
|
||||
local function seqstr2tbl(seqstr)
|
||||
local s = split(seqstr)
|
||||
local res = {}
|
||||
if (#s >= 1) then
|
||||
for sk, sv in pairs(s) do
|
||||
s2 = split(sv, '-')
|
||||
if(#s2 == 2) then
|
||||
table.insert(res, s2[1])
|
||||
table.insert(res, s2[2])
|
||||
end
|
||||
end
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
---
|
||||
-- return sequence-string from table
|
||||
function tbl2seqstr(seqtbl)
|
||||
local res=""
|
||||
if (istable(seqtbl)) then
|
||||
for sk, sv in pairs(seqtbl) do
|
||||
res=res..sv..((sk%2==0) and "," or "-")
|
||||
end
|
||||
if (string.sub(res, string.len(res))==",") then
|
||||
res=string.sub(res, 1, string.len(res)-1)
|
||||
end
|
||||
end
|
||||
return res
|
||||
local function tbl2seqstr(seqtbl)
|
||||
local res = ""
|
||||
if (istable(seqtbl)) then
|
||||
for sk, sv in pairs(seqtbl) do
|
||||
res = res..sv..((sk%2==0) and "," or "-")
|
||||
end
|
||||
if (string.sub(res, string.len(res))== ",") then
|
||||
res = string.sub(res, 1, string.len(res)-1)
|
||||
end
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
---
|
||||
|
|
|
@ -12,8 +12,10 @@ This is a script which automates cracking and dumping mifare classic cards. It s
|
|||
place by the device.
|
||||
|
||||
Arguments:
|
||||
-d debug logging on
|
||||
-h this help
|
||||
-h this help
|
||||
-d debug logging on
|
||||
-k known key for Sector 0 , keytype A
|
||||
|
||||
|
||||
Output files from this operation:
|
||||
<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
|
||||
typ = 4
|
||||
elseif 0x08 == sak then -- NXP MIFARE CLASSIC 1k | Plus 2k | Ev1 1K
|
||||
typ= 1
|
||||
typ = 1
|
||||
elseif 0x09 == sak then -- NXP MIFARE Mini 0.3k
|
||||
typ = 0
|
||||
elseif 0x10 == sak then-- "NXP MIFARE Plus 2k"
|
||||
elseif 0x10 == sak then-- "NXP MIFARE Plus 2k"
|
||||
typ = 2
|
||||
elseif 0x01 == sak then-- "NXP MIFARE TNP3xxx 1K"
|
||||
elseif 0x01 == sak then-- "NXP MIFARE TNP3xxx 1K"
|
||||
typ = 1
|
||||
else
|
||||
print("I don't know how many sectors there are on this type of card, defaulting to 16")
|
||||
|
@ -87,22 +89,40 @@ local function nested(key,sak)
|
|||
core.console(cmd)
|
||||
end
|
||||
|
||||
local function dump(uid)
|
||||
local function dump(uid, numsectors)
|
||||
dbg('dumping tag memory')
|
||||
|
||||
local typ = 1
|
||||
if 0x18 == sak then --NXP MIFARE Classic 4k | Plus 4k | Ev1 4k
|
||||
typ = 4
|
||||
elseif 0x08 == sak then -- NXP MIFARE CLASSIC 1k | Plus 2k | Ev1 1K
|
||||
typ = 1
|
||||
elseif 0x09 == sak then -- NXP MIFARE Mini 0.3k
|
||||
typ = 0
|
||||
elseif 0x10 == sak then-- "NXP MIFARE Plus 2k"
|
||||
typ = 2
|
||||
elseif 0x01 == sak then-- "NXP MIFARE TNP3xxx 1K"
|
||||
typ = 1
|
||||
end
|
||||
|
||||
if utils.confirm('Do you wish to create a memory dump of tag?') then
|
||||
|
||||
core.console("hf mf dump")
|
||||
local dumpfile = 'hf-mf-'..uid..'-data.bin'
|
||||
|
||||
local dmp = ('hf mf dump %s f %s'):format(typ, dumpfile)
|
||||
core.console(dmp)
|
||||
|
||||
-- Save the global args, those are *our* arguments
|
||||
local myargs = args
|
||||
-- Set the arguments for htmldump script
|
||||
args =("-o %s.html"):format(uid)
|
||||
args =('-i %s -o %s.html'):format(dumpfile, uid)
|
||||
-- call it
|
||||
require('../scripts/htmldump')
|
||||
require('htmldump')
|
||||
|
||||
args =""
|
||||
-- dump to emulator
|
||||
require('../scripts/dumptoemul')
|
||||
args =('-i %s -o %s.eml'):format(dumpfile, uid)
|
||||
require('dumptoemul')
|
||||
|
||||
-- Set back args. Not that it's used, just for the karma...
|
||||
args = myargs
|
||||
end
|
||||
|
@ -177,9 +197,9 @@ local function main(args)
|
|||
print("Found valid key: "..key);
|
||||
end
|
||||
-- Use nested attack
|
||||
nested(key,sak)
|
||||
nested(key, sak)
|
||||
-- Dump info
|
||||
dump(uid)
|
||||
dump(uid, sak)
|
||||
|
||||
if #key == 12 then exit = true end
|
||||
else
|
||||
|
|
|
@ -24,13 +24,13 @@ local example = "script run xxx"
|
|||
local author = "Martin Holst Swende & Asper"
|
||||
---
|
||||
-- PrintAndLog
|
||||
function prlog(...)
|
||||
local function prlog(...)
|
||||
-- TODO; replace this with a call to the proper PrintAndLog
|
||||
print(...)
|
||||
end
|
||||
---
|
||||
-- This is only meant to be used when errors occur
|
||||
function oops(err)
|
||||
local function oops(err)
|
||||
prlog("ERROR: ",err)
|
||||
return nil,err
|
||||
end
|
||||
|
@ -70,13 +70,13 @@ local utils = {
|
|||
|
||||
---
|
||||
-- Usage help
|
||||
function help()
|
||||
local function help()
|
||||
prlog(desc)
|
||||
prlog("Example usage")
|
||||
prlog(example)
|
||||
end
|
||||
|
||||
function debug(...)
|
||||
local function debug(...)
|
||||
if DEBUG then
|
||||
prlog("debug:", ...)
|
||||
end
|
||||
|
@ -158,7 +158,7 @@ end
|
|||
|
||||
--- This function is a lua-implementation of
|
||||
-- cmdhf14a.c:waitCmd(uint8_t iSelect)
|
||||
function waitCmd(iSelect)
|
||||
local function waitCmd(iSelect)
|
||||
local response = core.WaitForResponseTimeout(cmds.CMD_ACK,1000)
|
||||
if response then
|
||||
local count,cmd,arg0,arg1,arg2 = bin.unpack('LLLL',response)
|
||||
|
|
|
@ -21,6 +21,9 @@ Arguments:
|
|||
-o <offset> : memory offset, default is 0
|
||||
-l <length> : length in bytes, default is 256
|
||||
-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 =
|
||||
[[
|
||||
|
@ -67,7 +70,7 @@ local function main(args)
|
|||
local keylength = 4
|
||||
local usedkey = false
|
||||
|
||||
for o, a in getopt.getopt(args, 'ho:l:k:') do
|
||||
for o, a in getopt.getopt(args, 'ho:l:k:mti') do
|
||||
|
||||
-- help
|
||||
if o == "h" then return help() end
|
||||
|
@ -80,6 +83,10 @@ local function main(args)
|
|||
|
||||
-- keylength
|
||||
if o == "k" then keylength = tonumber(a); usedkey = true end
|
||||
|
||||
if o == "m" then keylength =6; usedkey = true; offset = 0x3F000-0x4000; end
|
||||
if o == "t" then keylength =4; usedkey = true; offset = 0x3F000-0x3000; end
|
||||
if o == "i" then keylength =8; usedkey = true; offset = 0x3F000-0x5000; end
|
||||
end
|
||||
|
||||
if length < 0 or length > 256 then
|
||||
|
|
|
@ -72,6 +72,7 @@ local function sendCmds( cmds )
|
|||
if cmds[i] then
|
||||
print ( cmds[i] )
|
||||
core.console( cmds[i] )
|
||||
core.clearCommandBuffer()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -37,13 +37,12 @@ Arguments:
|
|||
0020 - Swapforce
|
||||
]]
|
||||
|
||||
|
||||
-- This is only meant to be used when errors occur
|
||||
function oops(err)
|
||||
local function oops(err)
|
||||
print("ERROR: ",err)
|
||||
end
|
||||
-- Usage help
|
||||
function help()
|
||||
local function help()
|
||||
print(desc)
|
||||
print("Example usage")
|
||||
print(example)
|
||||
|
@ -64,7 +63,7 @@ local function waitCmd()
|
|||
end
|
||||
|
||||
local function readblock( blocknum, keyA )
|
||||
-- Read block 0
|
||||
-- Read block N
|
||||
cmd = Command:new{cmd = cmds.CMD_MIFARE_READBL, arg1 = blocknum, arg2 = 0, arg3 = 0, data = keyA}
|
||||
err = core.SendCommand(cmd:getBytes())
|
||||
if err then return nil, err end
|
||||
|
@ -72,8 +71,9 @@ local function readblock( blocknum, keyA )
|
|||
if err then return nil, err end
|
||||
return block0
|
||||
end
|
||||
|
||||
local function readmagicblock( blocknum )
|
||||
-- Read block 0
|
||||
-- Read block N
|
||||
local CSETBLOCK_SINGLE_OPERATION = 0x1F
|
||||
cmd = Command:new{cmd = cmds.CMD_MIFARE_CGETBLOCK, arg1 = CSETBLOCK_SINGLE_OPERATION, arg2 = 0, arg3 = blocknum}
|
||||
err = core.SendCommand(cmd:getBytes())
|
||||
|
@ -89,11 +89,13 @@ local function main(args)
|
|||
print( string.rep('--',20) )
|
||||
|
||||
local numBlocks = 64
|
||||
local cset = 'hf mf csetbl '
|
||||
local cset = 'hf mf csetbl '
|
||||
local csetuid = 'hf mf csetuid '
|
||||
local cget = 'hf mf cgetbl '
|
||||
local empty = '00000000000000000000000000000000'
|
||||
local AccAndKeyB = '7F078869000000000000'
|
||||
local AccAndKeyB = '7F0F0869000000000000'
|
||||
local atqa = '0F01'
|
||||
local sak = '81'
|
||||
-- Defaults to Gusto
|
||||
local toytype = 'C201'
|
||||
local subtype = '0030'
|
||||
|
@ -107,42 +109,43 @@ local function main(args)
|
|||
if o == "l" then return toys.List() end
|
||||
end
|
||||
|
||||
if #toytype ~= 4 then return oops('Wrong size - toytype. (4hex symbols)') end
|
||||
if #subtype ~= 4 then return oops('Wrong size - subtype. (4hex symbols)') end
|
||||
if #toytype ~= 4 then return oops('[!] Wrong size - toytype. (4hex symbols)') end
|
||||
if #subtype ~= 4 then return oops('[!] Wrong size - subtype. (4hex symbols)') end
|
||||
|
||||
-- look up type, find & validate types
|
||||
local item = toys.Find( toytype, subtype)
|
||||
if item then
|
||||
print( (' Looking up input: Found %s - %s (%s)'):format(item[6],item[5], item[4]) )
|
||||
print( ('[+] Looking up input: Found %s - %s (%s)'):format(item[6],item[5], item[4]) )
|
||||
else
|
||||
print('Didn\'t find item type. If you are sure about it, report it in')
|
||||
print('[-] Didn\'t find item type. If you are sure about it, post on forum')
|
||||
end
|
||||
--15,16
|
||||
--13-14
|
||||
|
||||
--13-14
|
||||
|
||||
-- find tag
|
||||
result, err = lib14a.read(false, true)
|
||||
if not result then return oops(err) end
|
||||
if not result then return oops(err) end
|
||||
|
||||
-- load keys
|
||||
local akeys = pre.GetAll(result.uid)
|
||||
local keyA = akeys:sub(1, 12 )
|
||||
local keyA = akeys:sub(1, 12 )
|
||||
|
||||
local b0 = readblock(0,keyA)
|
||||
local b0 = readblock(0, keyA)
|
||||
if not b0 then
|
||||
print('failed reading block with factorydefault key. Trying chinese magic read.')
|
||||
print('[-] failed reading block with factorydefault key. Trying chinese magic read.')
|
||||
b0, err = readmagicblock(0)
|
||||
if not b0 then
|
||||
oops(err)
|
||||
return oops('failed reading block with chinese magic command. quitting...')
|
||||
oops('[!] '..err)
|
||||
return oops('[!] failed reading block with chinese magic command. Quitting...')
|
||||
end
|
||||
end
|
||||
|
||||
-- wipe card.
|
||||
local cmd = (csetuid..'%s 0004 08 w'):format(result.uid)
|
||||
core.console(cmd)
|
||||
core.clearCommandBuffer()
|
||||
|
||||
-- wipe card.
|
||||
local cmd = (csetuid..'%s %s %s w'):format(result.uid, atqa, sak)
|
||||
core.console(cmd)
|
||||
core.clearCommandBuffer()
|
||||
|
||||
local b1 = toytype..string.rep('00',10)..subtype
|
||||
|
||||
local calc = utils.Crc16(b0..b1)
|
||||
|
@ -150,6 +153,7 @@ local function main(args)
|
|||
|
||||
local cmd = (cset..'1 %s%04x'):format( b1, calcEndian)
|
||||
core.console(cmd)
|
||||
core.clearCommandBuffer()
|
||||
|
||||
local pos, key
|
||||
for blockNo = 2, numBlocks-1, 1 do
|
||||
|
@ -161,5 +165,10 @@ local function main(args)
|
|||
end
|
||||
end
|
||||
core.clearCommandBuffer()
|
||||
|
||||
-- Set sector trailer S0, since it has different access rights
|
||||
cmd = ('%s 3 %s0f0f0f69000000000000'):format(cset, keyA)
|
||||
core.console(cmd)
|
||||
core.clearCommandBuffer()
|
||||
end
|
||||
main(args)
|
||||
main(args)
|
||||
|
|
|
@ -105,7 +105,7 @@ CborError _cbor_value_dup_string(const CborValue *value, void **buffer, size_t *
|
|||
return err;
|
||||
|
||||
++*buflen;
|
||||
*buffer = malloc(*buflen);
|
||||
*buffer = calloc(*buflen, sizeof(uint8_t));
|
||||
if (!*buffer) {
|
||||
/* out of memory */
|
||||
return CborErrorOutOfMemory;
|
||||
|
|
|
@ -178,7 +178,7 @@ static CborError dump_bytestring_base16(char **result, CborValue *it)
|
|||
return err;
|
||||
|
||||
/* a Base16 (hex) output is twice as big as our buffer */
|
||||
buffer = (uint8_t *)malloc(n * 2 + 1);
|
||||
buffer = (uint8_t *)calloc(n * 2 + 1, sizeof(uint8_t));
|
||||
*result = (char *)buffer;
|
||||
|
||||
/* let cbor_value_copy_byte_string know we have an extra byte for the terminating NUL */
|
||||
|
@ -204,7 +204,7 @@ static CborError generic_dump_base64(char **result, CborValue *it, const char al
|
|||
|
||||
/* a Base64 output (untruncated) has 4 bytes for every 3 in the input */
|
||||
size_t len = (n + 5) / 3 * 4;
|
||||
out = buffer = (uint8_t *)malloc(len + 1);
|
||||
out = buffer = (uint8_t *)calloc(len + 1, sizeof(uint8_t));
|
||||
*result = (char *)buffer;
|
||||
|
||||
/* we read our byte string at the tail end of the buffer
|
||||
|
|
|
@ -90,7 +90,7 @@ static int close_buffer(void *cookie)
|
|||
|
||||
FILE *open_memstream(char **bufptr, size_t *lenptr)
|
||||
{
|
||||
struct Buffer *b = (struct Buffer *)malloc(sizeof(struct Buffer));
|
||||
struct Buffer *b = (struct Buffer *)calloc(sizeof(struct Buffer), sizeof(uint8_t));
|
||||
if (b == NULL)
|
||||
return NULL;
|
||||
b->alloc = 0;
|
||||
|
|
|
@ -196,7 +196,7 @@ void SetFlushAfterWrite(bool value) {
|
|||
|
||||
int i,j;
|
||||
|
||||
int * output = (int* ) malloc(sizeof(int) * len);
|
||||
int * output = (int* ) calloc(sizeof(int) * len, sizeof(uint8_t));
|
||||
if ( !output ) return;
|
||||
|
||||
// clear mem
|
||||
|
|
|
@ -280,7 +280,7 @@ void sprint_bin_break_ex(uint8_t *src, size_t srclen, char *dest , uint8_t break
|
|||
printf("(sprint_bin_break) rowlen %d\n", rowlen);
|
||||
|
||||
// 3072 + end of line characters if broken at 8 bits
|
||||
dest = (char *)malloc(MAX_BIN_BREAK_LENGTH);
|
||||
dest = (char *)calloc(MAX_BIN_BREAK_LENGTH, sizeof(uint8_t));
|
||||
if (dest == NULL) return;
|
||||
|
||||
//clear memory
|
||||
|
@ -884,8 +884,8 @@ extern void strcreplace(char *buf, size_t len, char from, char to) {
|
|||
}
|
||||
|
||||
extern char *strmcopy(char *buf) {
|
||||
char* str = NULL;
|
||||
if ((str = (char*) malloc(strlen(buf) + 1)) != NULL) {
|
||||
char* str = (char*) calloc(strlen(buf) + 1, sizeof(uint8_t));
|
||||
if (str != NULL) {
|
||||
memset(str, 0, strlen(buf) + 1);
|
||||
strcpy(str, buf);
|
||||
}
|
||||
|
|
|
@ -178,6 +178,14 @@
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifndef DropFieldEx
|
||||
#define DropFieldEx(x) { \
|
||||
if ( (x) == ECC_CONTACTLESS) { \
|
||||
DropField(); \
|
||||
} \
|
||||
}
|
||||
#endif
|
||||
|
||||
extern uint8_t g_debugMode;
|
||||
|
||||
extern int ukbhit(void);
|
||||
|
|
|
@ -405,7 +405,7 @@ int nonce_distance(uint32_t from, uint32_t to)
|
|||
{
|
||||
uint16_t x, i;
|
||||
if(!dist) {
|
||||
dist = malloc(2 << 16);
|
||||
dist = calloc(2 << 16, sizeof(uint8_t));
|
||||
if(!dist)
|
||||
return -1;
|
||||
for (x = i = 1; i; ++i) {
|
||||
|
@ -443,7 +443,7 @@ static uint32_t fastfwd[2][8] = {
|
|||
*/
|
||||
uint32_t *lfsr_prefix_ks(uint8_t ks[8], int isodd)
|
||||
{
|
||||
uint32_t *candidates = malloc(4 << 10);
|
||||
uint32_t *candidates = calloc(4 << 10, sizeof(uint8_t));
|
||||
if (!candidates) return 0;
|
||||
|
||||
uint32_t c, entry;
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
// ISO15693 commons
|
||||
// Adrian Dabrowski 2010 and others, GPLv2
|
||||
//-----------------------------------------------------------------------------
|
||||
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
||||
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||
// the license.
|
||||
//-----------------------------------------------------------------------------
|
||||
// ISO15693 other commons
|
||||
//-----------------------------------------------------------------------------
|
||||
// Adrian Dabrowski 2010 and otherss
|
||||
// Christian Herrmann 2018
|
||||
|
||||
#ifndef ISO15693_H__
|
||||
|
|
|
@ -302,10 +302,10 @@ ISO 7816-4 Basic interindustry commands. For command APDU's.
|
|||
#define ISO7816_VERIFY 0x20
|
||||
#define ISO7816_INTERNAL_AUTHENTICATION 0x88
|
||||
#define ISO7816_EXTERNAL_AUTHENTICATION 0x82
|
||||
#define ISO7816_GET_CHALLENGE 0xB4
|
||||
#define ISO7816_GET_CHALLENGE 0x84
|
||||
#define ISO7816_MANAGE_CHANNEL 0x70
|
||||
|
||||
#define ISO7816_GETSTATUS 0xC0
|
||||
#define ISO7816_GET_RESPONSE 0xC0
|
||||
// ISO7816-4 For response APDU's
|
||||
#define ISO7816_OK 0x9000
|
||||
// 6x xx = ERROR
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
uint64_t * radixSort(uint64_t * array, uint32_t size) {
|
||||
rscounts_t counts;
|
||||
memset(&counts, 0, 256 * 8 * sizeof(uint32_t));
|
||||
uint64_t * cpy = (uint64_t *)malloc(size * sizeof(uint64_t));
|
||||
uint64_t * cpy = (uint64_t *)calloc(size * sizeof(uint64_t), sizeof(uint8_t));
|
||||
uint32_t o8=0, o7=0, o6=0, o5=0, o4=0, o3=0, o2=0, o1=0;
|
||||
uint32_t t8, t7, t6, t5, t4, t3, t2, t1;
|
||||
uint32_t x;
|
||||
|
|
|
@ -35,7 +35,8 @@ typedef enum ISO14A_COMMAND {
|
|||
ISO14A_SET_TIMEOUT = (1 << 6),
|
||||
ISO14A_NO_SELECT = (1 << 7),
|
||||
ISO14A_TOPAZMODE = (1 << 8),
|
||||
ISO14A_NO_RATS = (1 << 9)
|
||||
ISO14A_NO_RATS = (1 << 9),
|
||||
ISO14A_SEND_CHAINING = (1 << 10)
|
||||
} iso14a_command_t;
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -140,6 +140,8 @@ typedef struct{
|
|||
#define CMD_COTAG 0x0225
|
||||
#define CMD_SET_LF_T55XX_CONFIG 0x0226
|
||||
|
||||
#define CMD_T55XX_CHKPWDS 0x0230
|
||||
|
||||
/* CMD_SET_ADC_MUX: ext1 is 0 for lopkd, 1 for loraw, 2 for hipkd, 3 for hiraw */
|
||||
|
||||
// For the 13.56 MHz tags
|
||||
|
|
|
@ -8,4 +8,12 @@ get_crapto1:
|
|||
|
||||
get_nonce_bf:
|
||||
# git clone https://github.com/J-Run/mf_key_brute.git mf_key_brute
|
||||
git clone https://github.com/iceman1001/mf_nonce_brute mf_nonce_brute
|
||||
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
|
|
@ -28,7 +28,7 @@ my $clean = 2;
|
|||
# fatal: No names found, cannot describe anything.
|
||||
##
|
||||
# anyway forcing any kind of shell is at least useless, at worst fatal.
|
||||
my $commandGIT = "env -S which git";
|
||||
my $commandGIT = "env which git";
|
||||
|
||||
if ( defined($commandGIT) ) {
|
||||
|
||||
|
|
|
@ -68,14 +68,14 @@ typedef struct {
|
|||
} serial_port_unix;
|
||||
|
||||
// Set time-out on 30 miliseconds
|
||||
const struct timeval timeout = {
|
||||
struct timeval timeout = {
|
||||
.tv_sec = 0, // 0 second
|
||||
.tv_usec = 300000 // 300 000 micro seconds
|
||||
.tv_usec = 30000 // 30000 micro seconds
|
||||
};
|
||||
|
||||
serial_port uart_open(const char* pcPortName)
|
||||
{
|
||||
serial_port_unix* sp = malloc(sizeof(serial_port_unix));
|
||||
serial_port_unix* sp = calloc(sizeof(serial_port_unix), sizeof(uint8_t));
|
||||
if (sp == 0) return INVALID_SERIAL_PORT;
|
||||
|
||||
if (memcmp(pcPortName, "tcp:", 4) == 0) {
|
||||
|
@ -89,6 +89,10 @@ serial_port uart_open(const char* pcPortName)
|
|||
|
||||
char *colon = strrchr(addrstr, ':');
|
||||
char *portstr;
|
||||
|
||||
// Set time-out to 300 miliseconds only for TCP port
|
||||
timeout.tv_usec = 300000;
|
||||
|
||||
if (colon) {
|
||||
portstr = colon + 1;
|
||||
*colon = '\0';
|
||||
|
|
|
@ -50,7 +50,7 @@ typedef struct {
|
|||
|
||||
serial_port uart_open(const char* pcPortName) {
|
||||
char acPortName[255];
|
||||
serial_port_windows* sp = malloc(sizeof(serial_port_windows));
|
||||
serial_port_windows* sp = calloc(sizeof(serial_port_windows), sizeof(uint8_t));
|
||||
|
||||
if (sp == 0) {
|
||||
printf("[!] UART failed to allocate memory\n");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue