Merge pull request #6 from RfidResearchGroup/master

Update from upstream.
This commit is contained in:
DXL
2020-10-26 10:19:01 +08:00
committed by GitHub
96 changed files with 112808 additions and 2561 deletions
+55
View File
@@ -0,0 +1,55 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) Attach",
"type": "cppdbg",
"request": "attach",
"program": "${cwd}/client/proxmark3",
//"processId": "${command:pickProcess}",
"processId": "${input:ProcessID}",
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
},{
"name": "(gdb) Build & Launch",
"type": "cppdbg",
"request": "launch",
"program": "${cwd}/client/proxmark3",
"args": ["/dev/ttyACM0"],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
],
"preLaunchTask": "client: Debug: clean & make",
"miDebuggerPath": "/usr/bin/gdb"
}
],
"inputs": [
{
// Using Extension "Tasks Shell Input" https://marketplace.visualstudio.com/items?itemName=augustocdias.tasks-shell-input
"id": "ProcessID",
"type": "command",
"command": "shellCommand.execute",
"args": {
"command": "pgrep -n proxmark3",
}
}
]
}
+65 -7
View File
@@ -4,24 +4,82 @@
"version": "2.0.0",
"tasks": [
{
"label": "build",
"label": "all: Make & run",
"type": "shell",
"command": "make clean && make all -j$(nproc --all)",
"command": "make -j && ./pm3",
"problemMatcher": [
"$gcc"
]
],
"group": {
"kind": "build",
"isDefault": true
}
},
{
"label": "flash fullimage",
"label": "choose: Make",
"type": "shell",
"command": "sudo ./pm3-flash-fullimage",
"command": "make ${input:componentType} -j",
"problemMatcher": [
"$gcc"
],
"group": "build",
},
{
"label": "client: Debug: make",
"type": "shell",
"command": "make client -j DEBUG=1",
"problemMatcher": [
"$gcc"
],
"group": "build",
},
{
"label": "client: Debug: clean & make",
"type": "shell",
"command": "make client/clean && make client -j DEBUG=1",
"problemMatcher": [
"$gcc"
],
"group": "build",
},
{
"label": "fullimage: Make & Flash",
"type": "shell",
"command": "make fullimage && ./pm3-flash-fullimage",
"problemMatcher": []
},
{
"label": "FLASH BOOTROM",
"label": "BOOTROM: Make & Flash",
"type": "shell",
"command": "sudo ./pm3-flash-bootrom",
"command": "make bootrom && ./pm3-flash-bootrom",
"problemMatcher": []
},
{
"label": "Run client",
"type": "shell",
"command": "./pm3",
"problemMatcher": []
}
],
"inputs": [
{
"type": "pickString",
"id": "componentType",
"description": "What Makefile target do you want to execute?",
"options": [
"all",
"client",
"bootrom",
"fullimage",
"recovery",
"clean",
"install",
"uninstall",
"style",
"miscchecks",
"check",
],
"default": "all"
}
]
}
+1
View File
@@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file.
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
## [unreleased][unreleased]
- Removed 'hf iclass replay' - use the 'hf iclass dump' or 'hf iclass rdbl' with option "n" instead (@iceman1001). Concept taken from official repo (@pwpiwi)
- Add low level support for 14b' aka Innovatron (@doegox)
- Add doc/cliparser.md (@mwalker33)
- Add `hf 14b apdu` - send APDU over ISO14443B (@iceman1001)
+33 -12
View File
@@ -27,6 +27,9 @@ LD = g++
SH = sh
BASH = bash
PERL = perl
CCC =foo
CC_VERSION = $(shell $(CC) -dumpversion 2>/dev/null|sed 's/\..*//')
CC_VERSION := $(or $(strip $(CC_VERSION)),0)
PATHSEP=/
PREFIX ?= /usr/local
@@ -40,17 +43,29 @@ INSTALLDOCSRELPATH ?= share/doc/proxmark3
platform = $(shell uname)
DETECTED_OS=$(platform)
ifeq ($(platform),Darwin)
AR= /usr/bin/ar rcs
RANLIB= /usr/bin/ranlib
ifeq ($(shell $(CC) -v 2>&1 | grep -c "clang version"), 1)
DETECTED_COMPILER = clang
else
AR= ar rcs
RANLIB= ranlib
DETECTED_COMPILER = gcc
endif
DEFCXXFLAGS = -Wall -Werror -O3 -pipe
DEFCFLAGS = -Wall -Werror -O3 -fstrict-aliasing -pipe
DEFLDFLAGS =
ifeq ($(platform),Darwin)
AR= /usr/bin/ar rcs
RANLIB= /usr/bin/ranlib
else
AR= ar rcs
RANLIB= ranlib
endif
ifeq ($(DEBUG),1)
DEFCXXFLAGS = -g -O0 -pipe
DEFCFLAGS = -g -O0 -fstrict-aliasing -pipe
DEFLDFLAGS =
else
DEFCXXFLAGS = -Wall -Werror -O3 -pipe
DEFCFLAGS = -Wall -Werror -O3 -fstrict-aliasing -pipe
DEFLDFLAGS =
endif
# Next ones are activated only if SANITIZE=1
ifeq ($(SANITIZE),1)
DEFCFLAGS += -g -fsanitize=address -fno-omit-frame-pointer
@@ -62,12 +77,18 @@ DEFCFLAGS += -Wbad-function-cast -Wredundant-decls -Wmissing-prototypes -Wchar-s
# Some more warnings we need first to eliminate, so temporarely tolerated:
DEFCFLAGS += -Wcast-align -Wno-error=cast-align
DEFCFLAGS += -Wswitch-enum -Wno-error=switch-enum
# GCC 10 has issues with false positives on stringop-overflow, let's disable them for now (cf https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92955, https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94335)
# beware these flags didn't exist for GCC < 7
ifeq ($(shell expr $(CC_VERSION) \>= 10), 1)
ifneq ($(DETECTED_COMPILER), clang)
DEFCFLAGS += -Wno-stringop-overflow -Wno-error=stringop-overflow
endif
endif
ifeq ($(platform),Darwin)
# their readline has strict-prototype issues
DEFCFLAGS += -Wno-strict-prototypes
# their readline has strict-prototype issues
DEFCFLAGS += -Wno-strict-prototypes
else
DEFCFLAGS += -Wstrict-prototypes
DEFCFLAGS += -Wstrict-prototypes
endif
# Next ones are activated only if GCCEXTRA=1 or CLANGEXTRA=1
+5 -3
View File
@@ -302,15 +302,17 @@ static int reader_dump_mode(void) {
Iso15693InitReader();
set_tracing(false);
picopass_hdr *hdr = (picopass_hdr *)card_data;
// select tag.
uint32_t eof_time = 0;
bool res = select_iclass_tag(card_data, auth.use_credit_key, &eof_time);
bool res = select_iclass_tag(hdr, auth.use_credit_key, &eof_time);
if (res == false) {
switch_off();
continue;
}
picopass_hdr *hdr = (picopass_hdr *)card_data;
// sanity check of CSN.
if (hdr->csn[7] != 0xE0 && hdr->csn[6] != 0x12) {
switch_off();
@@ -366,7 +368,7 @@ static int reader_dump_mode(void) {
auth.use_credit_key = true;
memcpy(auth.key, aa2_key, sizeof(auth.key));
res = select_iclass_tag(card_data, auth.use_credit_key, &eof_time);
res = select_iclass_tag(hdr, auth.use_credit_key, &eof_time);
if (res) {
// sanity check of CSN.
+38 -24
View File
@@ -970,6 +970,23 @@ static void PacketReceived(PacketCommandNG *packet) {
);
break;
}
case CMD_LF_EM4X_LOGIN: {
struct p {
uint32_t password;
} PACKED;
struct p *payload = (struct p *) packet->data.asBytes;
EM4xLogin(payload->password);
break;
}
case CMD_LF_EM4X_BF: {
struct p {
uint32_t start_pwd;
uint32_t n;
} PACKED;
struct p *payload = (struct p *) packet->data.asBytes;
EM4xBruteforce(payload->start_pwd, payload->n);
break;
}
case CMD_LF_EM4X_READWORD: {
struct p {
uint32_t password;
@@ -1242,7 +1259,11 @@ static void PacketReceived(PacketCommandNG *packet) {
break;
}
case CMD_HF_ISO14443A_ANTIFUZZ: {
iso14443a_antifuzz(packet->oldarg[0]);
struct p {
uint8_t flag;
} PACKED;
struct p *payload = (struct p *) packet->data.asBytes;
iso14443a_antifuzz(payload->flag);
break;
}
case CMD_HF_EPA_COLLECT_NONCE: {
@@ -1473,12 +1494,12 @@ static void PacketReceived(PacketCommandNG *packet) {
MifareU_Otp_Tearoff(packet->oldarg[0], packet->oldarg[1], packet->data.asBytes);
break;
}
case CMD_HF_MFU_COUNTER_TEAROFF: {
case CMD_HF_MFU_COUNTER_TEAROFF: {
struct p {
uint8_t counter;
uint32_t tearoff_time;
} PACKED;
struct p *payload = (struct p *) packet->data.asBytes;
struct p *payload = (struct p *) packet->data.asBytes;
MifareU_Counter_Tearoff(payload->counter, payload->tearoff_time);
break;
}
@@ -1512,6 +1533,14 @@ static void PacketReceived(PacketCommandNG *packet) {
break;
}
case CMD_HF_ICLASS_SIMULATE: {
/*
struct p {
uint8_t reader[4];
uint8_t mac[4];
} PACKED;
struct p *payload = (struct p *) packet->data.asBytes;
*/
SimulateIClass(packet->oldarg[0], packet->oldarg[1], packet->oldarg[2], packet->data.asBytes);
break;
}
@@ -1519,15 +1548,6 @@ static void PacketReceived(PacketCommandNG *packet) {
ReaderIClass(packet->oldarg[0]);
break;
}
case CMD_HF_ICLASS_REPLAY: {
struct p {
uint8_t reader[4];
uint8_t mac[4];
} PACKED;
struct p *payload = (struct p *) packet->data.asBytes;
ReaderIClass_Replay(payload->reader, payload->mac);
break;
}
case CMD_HF_ICLASS_EML_MEMSET: {
//iceman, should call FPGADOWNLOAD before, since it corrupts BigBuf
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
@@ -1554,18 +1574,8 @@ static void PacketReceived(PacketCommandNG *packet) {
iClass_Dump(packet->data.asBytes);
break;
}
case CMD_HF_ICLASS_CLONE: {
struct p {
uint8_t startblock;
uint8_t endblock;
uint8_t data[];
} PACKED;
struct p *payload = (struct p *)packet->data.asBytes;
iClass_Clone(payload->startblock, payload->endblock, payload->data);
break;
}
case CMD_HF_ICLASS_RESTORE: {
iClass_Restore(packet->data.asBytes);
iClass_Restore((iclass_restore_req_t *)packet->data.asBytes);
break;
}
#endif
@@ -1607,7 +1617,11 @@ static void PacketReceived(PacketCommandNG *packet) {
break;
}
case CMD_SMART_SETCLOCK: {
SmartCardSetClock(packet->oldarg[0]);
struct p {
uint32_t new_clk;
} PACKED;
struct p *payload = (struct p *)packet->data.asBytes;
SmartCardSetClock(payload->new_clk);
break;
}
case CMD_SMART_RAW: {
+62 -38
View File
@@ -14,6 +14,7 @@
#include "lfadc.h"
#include "commonutil.h"
#include "em4x50.h"
#include "appmain.h" // tear
// 4 data bytes
// + byte with row parities
@@ -470,10 +471,12 @@ static bool find_double_listen_window(bool bcommand) {
if (bcommand) {
// SpinDelay(10);
// data transmission from card has to be stopped, because
// a commamd shall be issued
// unfortunately the posititon in listen window (where
// unfortunately the position in listen window (where
// command request has to be sent) has gone, so if a
// second window follows - sync on this to issue a command
@@ -519,7 +522,7 @@ static bool find_em4x50_tag(void) {
static bool request_receive_mode(void) {
// To issue a command we have to find a listen window first.
// Because identification and sychronization at the same time is not
// Because identification and synchronization at the same time is not
// possible when using pulse lengths a double listen window is used.
bool bcommand = true;
return find_double_listen_window(bcommand);
@@ -556,7 +559,7 @@ static bool check_ack(bool bliw) {
// "bit" of listen window)
wait_timer(FPGA_TIMER_0, T0 * 2 * EM4X50_T_TAG_FULL_PERIOD);
// check for listen window (if first bit cannot be inerpreted
// check for listen window (if first bit cannot be interpreted
// as a valid bit it must belong to a listen window)
if (get_next_bit() == EM4X50_BIT_OTHER) {
@@ -727,7 +730,7 @@ static bool standard_read(int *now) {
int fwr = *now;
uint8_t bits[EM4X50_TAG_WORD] = {0};
// start with the identification of two succsessive listening windows
// start with the identification of two successive listening windows
if (find_double_listen_window(false)) {
// read and save words until following double listen window is detected
@@ -816,7 +819,7 @@ void em4x50_info(em4x50_data_t *etd) {
status = (bsuccess << 1) + blogin;
lf_finalize();
reply_ng(CMD_ACK, status, (uint8_t *)tag.sectors, 238);
reply_ng(CMD_LF_EM4X50_INFO, status, (uint8_t *)tag.sectors, 238);
}
void em4x50_read(em4x50_data_t *etd) {
@@ -860,14 +863,13 @@ void em4x50_read(em4x50_data_t *etd) {
status = (now << 2) + (bsuccess << 1) + blogin;
lf_finalize();
reply_ng(CMD_ACK, status, (uint8_t *)tag.sectors, 238);
reply_ng(CMD_LF_EM4X50_READ, status, (uint8_t *)tag.sectors, 238);
}
//==============================================================================
// write functions
//==============================================================================
static bool write(uint8_t word[4], uint8_t address) {
static int write(uint8_t word[4], uint8_t address) {
// writes <word> to specified <address>
@@ -882,17 +884,23 @@ static bool write(uint8_t word[4], uint8_t address) {
// send data
em4x50_send_word(word);
// wait for T0 * EM4X50_T_TAG_TWA (write access time)
wait_timer(FPGA_TIMER_0, T0 * EM4X50_T_TAG_TWA);
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occurred
reply_ng(CMD_LF_EM4X50_WRITE, PM3_ETEAROFF, NULL, 0);
return PM3_ETEAROFF;
} else {
// look for ACK sequence
if (check_ack(false)) {
// wait for T0 * EM4X50_T_TAG_TWA (write access time)
wait_timer(FPGA_TIMER_0, T0 * EM4X50_T_TAG_TWA);
// now EM4x50 needs T0 * EM4X50_T_TAG_TWEE (EEPROM write time)
// for saving data and should return with ACK
if (check_ack(false))
return true;
// look for ACK sequence
if (check_ack(false)) {
// now EM4x50 needs T0 * EM4X50_T_TAG_TWEE (EEPROM write time)
// for saving data and should return with ACK
if (check_ack(false))
return PM3_SUCCESS;
}
}
} else {
@@ -900,10 +908,10 @@ static bool write(uint8_t word[4], uint8_t address) {
Dbprintf("error in command request");
}
return false;
return PM3_ESOFT;
}
static bool write_password(uint8_t password[4], uint8_t new_password[4]) {
static int write_password(uint8_t password[4], uint8_t new_password[4]) {
// changes password from <password> to <new_password>
@@ -915,23 +923,29 @@ static bool write_password(uint8_t password[4], uint8_t new_password[4]) {
// send address data
em4x50_send_word(password);
// wait for T0 * EM4x50_T_TAG_TPP (processing pause time)
wait_timer(FPGA_TIMER_0, T0 * EM4X50_T_TAG_TPP);
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occurred
reply_ng(CMD_LF_EM4X50_WRITE, PM3_ETEAROFF, NULL, 0);
return PM3_ETEAROFF;
} else {
// look for ACK sequence and send rm request
// during following listen window
if (check_ack(true)) {
// wait for T0 * EM4x50_T_TAG_TPP (processing pause time)
wait_timer(FPGA_TIMER_0, T0 * EM4X50_T_TAG_TPP);
// send new password
em4x50_send_word(new_password);
// look for ACK sequence and send rm request
// during following listen window
if (check_ack(true)) {
// wait for T0 * EM4X50_T_TAG_TWA (write access time)
wait_timer(FPGA_TIMER_0, T0 * EM4X50_T_TAG_TWA);
// send new password
em4x50_send_word(new_password);
// wait for T0 * EM4X50_T_TAG_TWA (write access time)
wait_timer(FPGA_TIMER_0, T0 * EM4X50_T_TAG_TWA);
if (check_ack(false))
if (check_ack(false))
return true;
if (check_ack(false))
return PM3_SUCCESS;
}
}
} else {
@@ -939,7 +953,7 @@ static bool write_password(uint8_t password[4], uint8_t new_password[4]) {
Dbprintf("error in command request");
}
return false;
return PM3_ESOFT;
}
void em4x50_write(em4x50_data_t *etd) {
@@ -966,8 +980,13 @@ void em4x50_write(em4x50_data_t *etd) {
blogin = login(etd->password);
// write word to given address
if (write(etd->word, etd->address)) {
int res = write(etd->word, etd->address);
if (res == PM3_ETEAROFF) {
lf_finalize();
return;
}
if (res == PM3_SUCCESS) {
// to verify result reset EM4x50
if (reset()) {
@@ -996,14 +1015,13 @@ void em4x50_write(em4x50_data_t *etd) {
}
status = (bsuccess << 1) + blogin;
lf_finalize();
reply_ng(CMD_ACK, status, (uint8_t *)tag.sectors, 238);
reply_ng(CMD_LF_EM4X50_WRITE, status, (uint8_t *)tag.sectors, 238);
}
void em4x50_write_password(em4x50_data_t *etd) {
// sinmple change of password
// simple change of password
bool bsuccess = false;
@@ -1015,12 +1033,18 @@ void em4x50_write_password(em4x50_data_t *etd) {
// login and change password
if (login(etd->password)) {
bsuccess = write_password(etd->password, etd->new_password);
int res = write_password(etd->password, etd->new_password);
if (res == PM3_ETEAROFF) {
lf_finalize();
return;
}
bsuccess = (res == PM3_SUCCESS);
}
}
lf_finalize();
reply_ng(CMD_ACK, bsuccess, 0, 0);
reply_ng(CMD_LF_EM4X50_WRITE_PASSWORD, bsuccess, 0, 0);
}
void em4x50_wipe(em4x50_data_t *etd) {
@@ -1049,7 +1073,7 @@ void em4x50_wipe(em4x50_data_t *etd) {
// to verify result reset EM4x50
if (reset()) {
// login not necessary because protectd word has been set to 0
// login not necessary because protected word has been set to 0
// -> no read protected words
// -> selective read can be called immediately
if (selective_read(addresses)) {
@@ -1078,5 +1102,5 @@ void em4x50_wipe(em4x50_data_t *etd) {
}
lf_finalize();
reply_ng(CMD_ACK, bsuccess, (uint8_t *)tag.sectors, 238);
reply_ng(CMD_LF_EM4X50_WIPE, bsuccess, (uint8_t *)tag.sectors, 238);
}
+18 -25
View File
@@ -47,12 +47,6 @@ static void __attribute__((optimize("O0"))) I2CSpinDelayClk(uint16_t delay) {
#define I2C_DELAY_2CLK I2CSpinDelayClk(2)
#define I2C_DELAY_XCLK(x) I2CSpinDelayClk((x))
#define I2C_DELAY_100us I2CSpinDelayClk( 100 / 3)
#define I2C_DELAY_600us I2CSpinDelayClk( 600 / 3)
#define I2C_DELAY_10ms I2CSpinDelayClk( 10 * 1000 / 3 )
#define I2C_DELAY_30ms I2CSpinDelayClk( 30 * 1000 / 3 )
#define I2C_DELAY_100ms I2CSpinDelayClk( 100 * 1000 / 3)
#define ISO7618_MAX_FRAME 255
// try i2c bus recovery at 100kHz = 5us high, 5us low
@@ -134,11 +128,11 @@ void I2C_Reset_EnterMainProgram(void) {
StartTicks();
I2C_init();
I2C_SetResetStatus(0, 0, 0);
I2C_DELAY_30ms;
WaitMS(30);
I2C_SetResetStatus(1, 0, 0);
I2C_DELAY_30ms;
WaitMS(30);
I2C_SetResetStatus(1, 1, 1);
I2C_DELAY_10ms;
WaitMS(10);
}
// Reset the SIM_Adapter, then enter the bootloader program
@@ -147,9 +141,9 @@ void I2C_Reset_EnterBootloader(void) {
StartTicks();
I2C_init();
I2C_SetResetStatus(0, 1, 1);
I2C_DELAY_100ms;
WaitMS(100);
I2C_SetResetStatus(1, 1, 1);
I2C_DELAY_10ms;
WaitMS(10);
}
// Wait for the clock to go High.
@@ -187,13 +181,13 @@ static bool WaitSCL_L(void) {
// It timeout reading response from card
// Which ever comes first
static bool WaitSCL_L_timeout(void) {
volatile uint32_t delay = 18000;
volatile uint32_t delay = 1800;
while (delay--) {
// exit on SCL LOW
if (!SCL_read)
return true;
I2C_DELAY_100us;
WaitMS(1);
}
return (delay == 0);
}
@@ -225,7 +219,7 @@ static bool I2C_WaitForSim(void) {
// 8051 speaks with smart card.
// 1000*50*3.07 = 153.5ms
// 1byte transfer == 1ms with max frame being 256bytes
if (!WaitSCL_H_delay(30 * 1000 * 50))
if (!WaitSCL_H_delay(20 * 1000 * 50))
return false;
return true;
@@ -440,8 +434,7 @@ int16_t I2C_BufferRead(uint8_t *data, uint8_t len, uint8_t device_cmd, uint8_t d
// extra wait 500us (514us measured)
// 200us (xx measured)
// WaitUS(600);
I2C_DELAY_600us;
WaitUS(600);
bool bBreak = true;
uint16_t readcount = 0;
@@ -641,6 +634,9 @@ bool sc_rx_bytes(uint8_t *dest, uint8_t *destlen) {
len = I2C_BufferRead(dest, *destlen, I2C_DEVICE_CMD_READ, I2C_DEVICE_ADDRESS_MAIN);
LED_C_ON();
if (len > 1) {
break;
} else if (len == 1) {
@@ -674,7 +670,7 @@ bool GetATR(smart_card_atr_t *card_ptr, bool verbose) {
// 1byte = 1ms , max frame 256bytes. Should wait 256ms atleast just in case.
if (I2C_WaitForSim() == false)
return false;
// read bytes from module
uint8_t len = sizeof(card_ptr->atr);
if (sc_rx_bytes(card_ptr->atr, &len) == false)
@@ -713,12 +709,12 @@ bool GetATR(smart_card_atr_t *card_ptr, bool verbose) {
}
void SmartCardAtr(void) {
smart_card_atr_t card;
LED_D_ON();
set_tracing(true);
I2C_Reset_EnterMainProgram();
bool isOK = GetATR(&card, true);
reply_mix(CMD_ACK, isOK, sizeof(smart_card_atr_t), 0, &card, sizeof(smart_card_atr_t));
smart_card_atr_t card;
int res = GetATR(&card, true) ? PM3_SUCCESS : PM3_ETIMEOUT;
reply_ng(CMD_SMART_ATR, res, (uint8_t*)&card, sizeof(smart_card_atr_t));
set_tracing(false);
LEDsoff();
}
@@ -811,8 +807,7 @@ void SmartCardUpgrade(uint64_t arg0) {
}
// writing takes time.
// WaitMS(50);
I2C_DELAY_100ms;
WaitMS(100);
// read
res = I2C_ReadFW(verfiydata, size, msb, lsb, I2C_DEVICE_ADDRESS_BOOT);
@@ -844,12 +839,10 @@ void SmartCardSetClock(uint64_t arg0) {
LED_D_ON();
set_tracing(true);
I2C_Reset_EnterMainProgram();
// Send SIM CLC
// start [C0 05 xx] stop
I2C_WriteByte(arg0, I2C_DEVICE_CMD_SIM_CLC, I2C_DEVICE_ADDRESS_MAIN);
reply_mix(CMD_ACK, 1, 0, 0, 0, 0);
reply_ng(CMD_SMART_SETCLOCK, PM3_SUCCESS, NULL, 0);
set_tracing(false);
LEDsoff();
}
+132 -149
View File
@@ -1276,7 +1276,7 @@ static bool iclass_send_cmd_with_retries(uint8_t *cmd, size_t cmdsize, uint8_t *
* @return false = fail
* true = Got all.
*/
static bool select_iclass_tag_ex(uint8_t *card_data, bool use_credit_key, uint32_t *eof_time, uint8_t *status) {
static bool select_iclass_tag_ex(picopass_hdr *hdr, bool use_credit_key, uint32_t *eof_time, uint8_t *status) {
static uint8_t act_all[] = { ICLASS_CMD_ACTALL };
static uint8_t identify[] = { ICLASS_CMD_READ_OR_IDENTIFY, 0x00, 0x73, 0x33 };
@@ -1286,8 +1286,6 @@ static bool select_iclass_tag_ex(uint8_t *card_data, bool use_credit_key, uint32
uint8_t read_check_cc[] = { 0x80 | ICLASS_CMD_READCHECK, 0x02 };
uint8_t resp[ICLASS_BUFFER_SIZE] = {0};
picopass_hdr *hdr = (picopass_hdr *)card_data;
// Bit 4: K.If this bit equals to one, the READCHECK will use the Credit Key (Kc); if equals to zero, Debit Key (Kd) will be used
// bit 7: parity.
if (use_credit_key)
@@ -1370,6 +1368,8 @@ static bool select_iclass_tag_ex(uint8_t *card_data, bool use_credit_key, uint32
} else {
// on NON_SECURE_PAGEMODE cards, AIA is on block2..
// read App Issuer Area block 2
read_aia[1] = 0x02;
read_aia[2] = 0x61;
@@ -1385,23 +1385,23 @@ static bool select_iclass_tag_ex(uint8_t *card_data, bool use_credit_key, uint32
if (status) {
*status |= FLAG_ICLASS_AIA;
memcpy(card_data + (8 * 2), resp, 8);
memcpy(hdr->epurse, resp, sizeof(hdr->epurse));
}
}
return true;
}
bool select_iclass_tag(uint8_t *card_data, bool use_credit_key, uint32_t *eof_time) {
bool select_iclass_tag(picopass_hdr *hdr, bool use_credit_key, uint32_t *eof_time) {
uint8_t result = 0;
return select_iclass_tag_ex(card_data, use_credit_key, eof_time, &result);
return select_iclass_tag_ex(hdr, use_credit_key, eof_time, &result);
}
// Reader iClass Anticollission
// turn off afterwards
void ReaderIClass(uint8_t flags) {
uint8_t card_data[6 * 8] = {0xFF};
picopass_hdr hdr = {0};
// uint8_t last_csn[8] = {0, 0, 0, 0, 0, 0, 0, 0};
uint8_t resp[ICLASS_BUFFER_SIZE] = {0};
memset(resp, 0xFF, sizeof(resp));
@@ -1419,14 +1419,13 @@ void ReaderIClass(uint8_t flags) {
uint8_t result_status = 0;
uint32_t eof_time = 0;
bool status = select_iclass_tag_ex(card_data, use_credit_key, &eof_time, &result_status);
bool status = select_iclass_tag_ex(&hdr, use_credit_key, &eof_time, &result_status);
if (status == false) {
reply_mix(CMD_ACK, 0xFF, 0, 0, card_data, 0);
reply_mix(CMD_ACK, 0xFF, 0, 0, NULL, 0);
switch_off();
return;
}
// Page mapping for secure mode
// 0 : CSN
// 1 : Configuration
@@ -1444,7 +1443,7 @@ void ReaderIClass(uint8_t flags) {
// with 0xFF:s in block 3 and 4.
LED_B_ON();
reply_mix(CMD_ACK, result_status, 0, 0, card_data, sizeof(card_data));
reply_mix(CMD_ACK, result_status, 0, 0, (uint8_t *)&hdr, sizeof(hdr));
//Send back to client, but don't bother if we already sent this -
// only useful if looping in arm (not try_once && not abort_after_read)
@@ -1470,101 +1469,6 @@ void ReaderIClass(uint8_t flags) {
switch_off();
}
// turn off afterwards
void ReaderIClass_Replay(uint8_t *rnr, uint8_t *mac) {
BigBuf_free();
uint8_t check[] = { ICLASS_CMD_CHECK, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
memcpy(check + 1, rnr, 4);
memcpy(check + 5, mac, 4);
uint8_t *card_data = BigBuf_malloc(ICLASS_16KS_SIZE);
if (card_data == NULL) {
DbpString("fail to allocate memory");
reply_ng(CMD_HF_ICLASS_REPLAY, PM3_EMALLOC, NULL, 0);
return;
}
memset(card_data, 0xFF, ICLASS_16KS_SIZE);
uint32_t start_time = 0;
uint32_t eof_time = 0;
Iso15693InitReader();
picopass_hdr hdr = {0};
bool res = select_iclass_tag((uint8_t *)&hdr, false, &eof_time);
if (res == false) {
reply_ng(CMD_HF_ICLASS_REPLAY, PM3_ETIMEOUT, NULL, 0);
switch_off();
return;
}
uint8_t resp[10] = {0};
//for now replay captured auth (as cc not updated)
start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
res = iclass_send_cmd_with_retries(check, sizeof(check), resp, sizeof(resp), 4, 3, &start_time, ICLASS_READER_TIMEOUT_OTHERS, &eof_time);
if (res == false) {
reply_ng(CMD_HF_ICLASS_REPLAY, PM3_ETIMEOUT, NULL, 0);
switch_off();
return;
}
uint8_t mem = hdr.conf.mem_config;
uint8_t cardsize = ((mem & 0x80) == 0x80) ? 255 : 32;
/*
static struct memory_t {
int k16;
int book;
int k2;
int lockauth;
int keyaccess;
} memory;
// memory.k16 = ((mem & 0x80) == 0x80);
// memory.book = ((mem & 0x20) == 0x20);
// memory.k2 = ((mem & 0x08) == 0x08);
// memory.lockauth = ((mem & 0x02) == 0x02);
// memory.keyaccess = ((mem & 0x01) == 0x01);
// uint8_t cardsize = memory.k16 ? 255 : 32;
*/
bool dumpsuccess = true;
// main read loop
uint16_t i;
for (i = 0; i <= cardsize; i++) {
uint8_t c[] = {ICLASS_CMD_READ_OR_IDENTIFY, i, 0x00, 0x00};
AddCrc(c + 1, 1);
res = iclass_send_cmd_with_retries(c, sizeof(c), resp, sizeof(resp), 10, 3, &start_time, ICLASS_READER_TIMEOUT_OTHERS, &eof_time);
if (res) {
memcpy(card_data + (8 * i), resp, 8);
} else {
Dbprintf("failed to read block %u ( 0x%02x)", i, i);
dumpsuccess = false;
}
}
struct p {
bool isOK;
uint16_t block_cnt;
uint32_t bb_offset;
} PACKED response;
response.isOK = dumpsuccess;
response.block_cnt = i;
response.bb_offset = card_data - BigBuf_get_addr();
reply_ng(CMD_HF_ICLASS_REPLAY, PM3_SUCCESS, (uint8_t *)&response, sizeof(response));
BigBuf_free();
switch_off();
}
// used with function select_and_auth (cmdhficlass.c)
// which needs to authenticate before doing more things like read/write
// selects and authenticate to a card, sends back div_key and mac to client.
@@ -1585,24 +1489,30 @@ bool authenticate_iclass_tag(iclass_auth_req_t *payload, picopass_hdr *hdr, uint
memcpy(ccnr, hdr->epurse, sizeof(hdr->epurse));
if (payload->use_raw)
memcpy(div_key, payload->key, 8);
else
iclass_calc_div_key(hdr->csn, payload->key, div_key, payload->use_elite);
if (payload->use_replay) {
if (payload->use_credit_key)
memcpy(hdr->key_c, div_key, sizeof(hdr->key_c));
else
memcpy(hdr->key_d, div_key, sizeof(hdr->key_d));
memcpy(pmac, payload->key + 4, 4);
memcpy(cmd_check + 1, payload->key, 8);
opt_doReaderMAC(ccnr, div_key, pmac);
} else {
if (payload->use_raw)
memcpy(div_key, payload->key, 8);
else
iclass_calc_div_key(hdr->csn, payload->key, div_key, payload->use_elite);
// copy MAC to check command (readersignature)
cmd_check[5] = pmac[0];
cmd_check[6] = pmac[1];
cmd_check[7] = pmac[2];
cmd_check[8] = pmac[3];
if (payload->use_credit_key)
memcpy(hdr->key_c, div_key, sizeof(hdr->key_c));
else
memcpy(hdr->key_d, div_key, sizeof(hdr->key_d));
opt_doReaderMAC(ccnr, div_key, pmac);
// copy MAC to check command (readersignature)
cmd_check[5] = pmac[0];
cmd_check[6] = pmac[1];
cmd_check[7] = pmac[2];
cmd_check[8] = pmac[3];
}
return iclass_send_cmd_with_retries(cmd_check, sizeof(cmd_check), resp_auth, sizeof(resp_auth), 4, 2, start_time, ICLASS_READER_TIMEOUT_OTHERS, eof_time);
}
@@ -1632,7 +1542,7 @@ void iClass_Authentication_fast(uint64_t arg0, uint64_t arg1, uint8_t *datain) {
readcheck_cc[0] = 0x10 | ICLASS_CMD_READCHECK;
// select card / e-purse
uint8_t card_data[6 * 8] = {0};
picopass_hdr hdr = {0};
iclass_premac_t *keys = (iclass_premac_t *)datain;
@@ -1646,7 +1556,7 @@ void iClass_Authentication_fast(uint64_t arg0, uint64_t arg1, uint8_t *datain) {
uint32_t start_time = 0, eof_time = 0;
if (select_iclass_tag(card_data, use_credit_key, &eof_time) == false)
if (select_iclass_tag(&hdr, use_credit_key, &eof_time) == false)
goto out;
start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
@@ -1723,7 +1633,7 @@ void iClass_ReadBlock(uint8_t *msg) {
// select tag.
uint32_t eof_time = 0;
picopass_hdr hdr = {0};
bool res = select_iclass_tag((uint8_t *)&hdr, payload->use_credit_key, &eof_time);
bool res = select_iclass_tag(&hdr, payload->use_credit_key, &eof_time);
if (res == false) {
if (payload->send_reply) {
response.isOK = res;
@@ -1796,7 +1706,7 @@ void iClass_Dump(uint8_t *msg) {
// select tag.
uint32_t eof_time = 0;
picopass_hdr hdr = {0};
bool res = select_iclass_tag((uint8_t *)&hdr, req->use_credit_key, &eof_time);
bool res = select_iclass_tag(&hdr, req->use_credit_key, &eof_time);
if (res == false) {
if (req->send_reply) {
reply_ng(CMD_HF_ICLASS_DUMP, PM3_ETIMEOUT, NULL, 0);
@@ -1866,10 +1776,12 @@ void iClass_Dump(uint8_t *msg) {
BigBuf_free();
}
static bool iclass_writeblock_ext(uint8_t blockno, uint8_t *data) {
static bool iclass_writeblock_ext(uint8_t blockno, uint8_t *data, uint8_t *mac) {
// write command: cmd, 1 blockno, 8 data, 4 mac
uint8_t write[16] = { 0x80 | ICLASS_CMD_UPDATE, blockno };
memcpy(write + 2, data, 12); // data + mac
memcpy(write + 2, data, 8);
memcpy(write + 10, mac, 4);
AddCrc(write + 1, 13);
uint8_t resp[10] = {0};
@@ -1914,7 +1826,7 @@ void iClass_WriteBlock(uint8_t *msg) {
// select tag.
uint32_t eof_time = 0;
picopass_hdr hdr = {0};
bool res = select_iclass_tag((uint8_t *)&hdr, payload->req.use_credit_key, &eof_time);
bool res = select_iclass_tag(&hdr, payload->req.use_credit_key, &eof_time);
if (res == false) {
goto out;
}
@@ -1937,10 +1849,14 @@ void iClass_WriteBlock(uint8_t *msg) {
wb[0] = payload->req.blockno;
memcpy(wb + 1, payload->data, 8);
if (payload->req.use_credit_key)
doMAC_N(wb, sizeof(wb), hdr.key_c, mac);
else
doMAC_N(wb, sizeof(wb), hdr.key_d, mac);
if (payload->req.use_replay) {
doMAC_N(wb, sizeof(wb), payload->req.key + 4, mac);
} else {
if (payload->req.use_credit_key)
doMAC_N(wb, sizeof(wb), hdr.key_c, mac);
else
doMAC_N(wb, sizeof(wb), hdr.key_d, mac);
}
memcpy(write + 2, payload->data, 8); // data
memcpy(write + 10, mac, sizeof(mac)); // mac
@@ -1949,8 +1865,29 @@ void iClass_WriteBlock(uint8_t *msg) {
start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
uint8_t resp[10] = {0};
res = iclass_send_cmd_with_retries(write, sizeof(write), resp, sizeof(resp), 10, 3, &start_time, ICLASS_READER_TIMEOUT_UPDATE, &eof_time);
if (res == false) {
uint8_t tries = 3;
while (tries-- > 0) {
iclass_send_as_reader(write, sizeof(write), &start_time, &eof_time);
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occured
res = false;
switch_off();
if (payload->req.send_reply)
reply_ng(CMD_HF_ICLASS_WRITEBL, PM3_ETEAROFF, (uint8_t *)&res, sizeof(uint8_t));
return;
} else {
if (GetIso15693AnswerFromTag(resp, sizeof(resp), ICLASS_READER_TIMEOUT_UPDATE, &eof_time) == 10) {
res = true;
break;
}
}
}
if (tries == 0) {
res = false;
goto out;
}
@@ -1983,29 +1920,75 @@ out:
reply_ng(CMD_HF_ICLASS_WRITEBL, PM3_SUCCESS, (uint8_t *)&res, sizeof(uint8_t));
}
// turn off afterwards
void iClass_Clone(uint8_t startblock, uint8_t endblock, uint8_t *data) {
}
void iClass_Restore(iclass_restore_req_t *msg) {
void iClass_Restore(uint8_t *msg) {
// sanitation
if (msg == NULL) {
reply_ng(CMD_HF_ICLASS_RESTORE, PM3_ESOFT, NULL, 0);
return;
}
iclass_restore_req_t *cmd = (iclass_restore_req_t *)msg;
// iclass_auth_req_t *req = &cmd->req;
if (msg->item_cnt == 0) {
if (msg->req.send_reply) {
reply_ng(CMD_HF_ICLASS_RESTORE, PM3_ESOFT, NULL, 0);
}
return;
}
LED_A_ON();
uint16_t written = 0;
uint16_t total_blocks = (cmd->end_block - cmd->start_block) + 1;
for (uint8_t b = cmd->start_block; b < total_blocks; b++) {
Iso15693InitReader();
if (iclass_writeblock_ext(b, cmd->data + ((b - cmd->start_block) * 12))) {
Dbprintf("Write block [%02x] successful", b);
written++;
} else {
Dbprintf("Write block [%02x] failed", b);
uint16_t written = 0;
uint32_t eof_time = 0;
picopass_hdr hdr = {0};
// select
bool res = select_iclass_tag(&hdr, msg->req.use_credit_key, &eof_time);
if (res == false) {
goto out;
}
// authenticate
uint8_t mac[4] = {0};
uint32_t start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
// authenticate
if (msg->req.do_auth) {
res = authenticate_iclass_tag(&msg->req, &hdr, &start_time, &eof_time, mac);
if (res == false) {
goto out;
}
}
// main loop
for (uint8_t i = 0; i < msg->item_cnt; i++) {
iclass_restore_item_t item = msg->blocks[i];
// calc new mac for data, using 1b blockno, 8b data,
uint8_t wb[9] = {0};
wb[0] = item.blockno;
memcpy(wb + 1, item.data, 8);
if (msg->req.use_credit_key)
doMAC_N(wb, sizeof(wb), hdr.key_c, mac);
else
doMAC_N(wb, sizeof(wb), hdr.key_d, mac);
// data + mac
if (iclass_writeblock_ext(item.blockno, item.data, mac)) {
Dbprintf("Write block [%02x] " _GREEN_("successful"), item.blockno);
written++;
} else {
Dbprintf("Write block [%02x] " _RED_("failed"), item.blockno);
}
}
out:
switch_off();
uint8_t isOK = (written == total_blocks) ? 1 : 0;
reply_ng(CMD_HF_ICLASS_CLONE, PM3_SUCCESS, (uint8_t *)&isOK, sizeof(uint8_t));
if (msg->req.send_reply) {
int isOK = (written == msg->item_cnt) ? PM3_SUCCESS : PM3_ESOFT;
reply_ng(CMD_HF_ICLASS_RESTORE, isOK, NULL, 0);
}
}
+2 -4
View File
@@ -17,13 +17,11 @@
void SniffIClass(uint8_t jam_search_len, uint8_t *jam_search_string);
void ReaderIClass(uint8_t arg0);
void ReaderIClass_Replay(uint8_t *rnr, uint8_t *mac);
void iClass_WriteBlock(uint8_t *msg);
void iClass_Dump(uint8_t *msg);
void iClass_Restore(uint8_t *msg);
void iClass_Clone(uint8_t startblock, uint8_t endblock, uint8_t *data);
void iClass_Restore(iclass_restore_req_t *msg);
int do_iclass_simulation_nonsec(void);
int do_iclass_simulation(int simulationMode, uint8_t *reader_mac_buf);
@@ -37,6 +35,6 @@ bool iclass_auth(iclass_auth_req_t *payload, uint8_t *out);
void iClass_ReadBlock(uint8_t *msg);
bool iclass_read_block(uint16_t blockno, uint8_t *data, uint32_t *start_time, uint32_t *eof_time);
bool select_iclass_tag(uint8_t *card_data, bool use_credit_key, uint32_t *eof_time);
bool select_iclass_tag(picopass_hdr *hdr, bool use_credit_key, uint32_t *eof_time);
bool authenticate_iclass_tag(iclass_auth_req_t *payload, picopass_hdr *hdr, uint32_t *start_time, uint32_t *eof_time, uint8_t *mac_out);
#endif
+12 -9
View File
@@ -1778,9 +1778,10 @@ static void PrepareDelayedTransfer(uint16_t delay) {
//-------------------------------------------------------------------------------------
static void TransmitFor14443a(const uint8_t *cmd, uint16_t len, uint32_t *timing) {
if (!hf_field_active)
if (!hf_field_active) {
Dbprintf("Warning: HF field is off, ignoring TransmitFor14443a command");
return;
}
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);
if (timing) {
@@ -2189,8 +2190,10 @@ bool EmLogTrace(uint8_t *reader_data, uint16_t reader_len, uint32_t reader_Start
//-----------------------------------------------------------------------------
bool GetIso14443aAnswerFromTag_Thinfilm(uint8_t *receivedResponse, uint8_t *received_len) {
if (!hf_field_active)
if (!hf_field_active) {
Dbprintf("Warning: HF field is off, ignoring GetIso14443aAnswerFromTag_Thinfilm command");
return false;
}
// Set FPGA mode to "reader listen mode", no modulation (listen
// only, since we are receiving, not transmitting).
@@ -2390,7 +2393,7 @@ void iso14443a_antifuzz(uint32_t flags) {
}
}
reply_old(CMD_ACK, 1, 0, 0, 0, 0);
reply_ng(CMD_HF_ISO14443A_ANTIFUZZ, PM3_SUCCESS, NULL, 0);
switch_off();
BigBuf_free_keep_EM();
}
@@ -2624,13 +2627,13 @@ int iso14443a_select_card(uint8_t *uid_ptr, iso14a_card_select_t *p_card, uint32
} // else force RATS
// RATS, Request for answer to select
if (!no_rats) {
uint8_t rats[] = { ISO14443A_CMD_RATS, 0x80, 0x00, 0x00 }; // FSD=256, FSDI=8, CID=0
if (no_rats == false) {
uint8_t rats[] = { ISO14443A_CMD_RATS, 0x80, 0x00, 0x00 }; // FSD=256, FSDI=8, CID=0
AddCrc14A(rats, 2);
ReaderTransmit(rats, sizeof(rats), NULL);
int len = ReaderReceive(resp, resp_par);
if (!len) return 0;
if (len == 0)
return 0;
if (p_card) {
memcpy(p_card->ats, resp, sizeof(p_card->ats));
@@ -2932,7 +2935,7 @@ void ReaderIso14443a(PacketCommandNG *c) {
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occured
FpgaDisableTracing();
reply_old(CMD_ACK, 0, 0, 0, NULL, 0);
reply_mix(CMD_ACK, 0, 0, 0, NULL, 0);
} else {
arg0 = ReaderReceive(buf, par);
FpgaDisableTracing();
+10 -5
View File
@@ -1895,12 +1895,17 @@ void SendRawCommand14443B_Ex(PacketCommandNG *c) {
uint32_t eof_time = 0;
CodeAndTransmit14443bAsReader(cmd, len, &start_time, &eof_time);
eof_time += DELAY_ISO14443B_VCD_TO_VICC_READER;
status = Get14443bAnswerFromTag(buf, sizeof(buf), 5 * ISO14443B_READER_TIMEOUT, &eof_time); // raw
FpgaDisableTracing();
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occured
FpgaDisableTracing();
reply_mix(CMD_HF_ISO14443B_COMMAND, -2, 0, 0, NULL, 0);
} else {
eof_time += DELAY_ISO14443B_VCD_TO_VICC_READER;
status = Get14443bAnswerFromTag(buf, sizeof(buf), 5 * ISO14443B_READER_TIMEOUT, &eof_time); // raw
FpgaDisableTracing();
sendlen = MIN(Demod.len, PM3_CMD_DATA_SIZE);
reply_mix(CMD_HF_ISO14443B_COMMAND, status, sendlen, 0, Demod.output, sendlen);
sendlen = MIN(Demod.len, PM3_CMD_DATA_SIZE);
reply_mix(CMD_HF_ISO14443B_COMMAND, status, sendlen, 0, Demod.output, sendlen);
}
}
out:
+81 -72
View File
@@ -290,6 +290,7 @@ void TransmitTo15693Tag(const uint8_t *cmd, int len, uint32_t *start_time) {
LED_B_OFF();
*start_time = *start_time + DELAY_ARM_TO_TAG;
FpgaDisableTracing();
}
//-----------------------------------------------------------------------------
@@ -732,6 +733,7 @@ int GetIso15693AnswerFromTag(uint8_t *response, uint16_t max_len, uint16_t timeo
}
FpgaDisableSscDma();
FpgaDisableTracing();
uint32_t sof_time = *eof_time
- (dt->len * 8 * 8 * 16) // time for byte transfers
@@ -1469,17 +1471,22 @@ int SendDataTag(uint8_t *send, int sendlen, bool init, bool speed_fast, uint8_t
// low speed (1 out of 256)
CodeIso15693AsReader256(send, sendlen);
}
int res = 0;
tosend_t *ts = get_tosend();
TransmitTo15693Tag(ts->buf, ts->max, &start_time);
*eof_time = start_time + 32 * ((8 * ts->max) - 4); // substract the 4 padding bits after EOF
LogTrace_ISO15693(send, sendlen, (start_time * 4), (*eof_time * 4), NULL, true);
int res = 0;
if (recv != NULL) {
res = GetIso15693AnswerFromTag(recv, max_recv_len, timeout, eof_time);
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occured
res = PM3_ETEAROFF;
} else {
*eof_time = start_time + 32 * ((8 * ts->max) - 4); // substract the 4 padding bits after EOF
LogTrace_ISO15693(send, sendlen, (start_time * 4), (*eof_time * 4), NULL, true);
if (recv != NULL) {
res = GetIso15693AnswerFromTag(recv, max_recv_len, timeout, eof_time);
}
}
FpgaDisableTracing();
return res;
}
@@ -1495,7 +1502,6 @@ int SendDataTagEOF(uint8_t *recv, uint16_t max_recv_len, uint32_t start_time, ui
if (recv != NULL) {
res = GetIso15693AnswerFromTag(recv, max_recv_len, timeout, eof_time);
}
FpgaDisableTracing();
return res;
}
@@ -1588,41 +1594,49 @@ void ReaderIso15693(uint32_t parameter) {
BuildIdentifyRequest(cmd);
uint32_t start_time = 0;
uint32_t eof_time;
int answerLen = SendDataTag(cmd, sizeof(cmd), true, true, answer, ISO15693_MAX_RESPONSE_LENGTH, start_time, ISO15693_READER_TIMEOUT, &eof_time);
start_time = eof_time + DELAY_ISO15693_VICC_TO_VCD_READER;
int recvlen = SendDataTag(cmd, sizeof(cmd), true, true, answer, ISO15693_MAX_RESPONSE_LENGTH, start_time, ISO15693_READER_TIMEOUT, &eof_time);
// we should do a better check than this
if (answerLen >= 12) {
uint8_t uid[8];
uid[0] = answer[9]; // always E0
uid[1] = answer[8]; // IC Manufacturer code
uid[2] = answer[7];
uid[3] = answer[6];
uid[4] = answer[5];
uid[5] = answer[4];
uid[6] = answer[3];
uid[7] = answer[2];
if (recvlen == PM3_ETEAROFF) { // tearoff occured
reply_mix(CMD_ACK, recvlen, 0, 0, NULL, 0);
} else {
if (DBGLEVEL >= DBG_EXTENDED) {
Dbprintf("[+] UID = %02X%02X%02X%02X%02X%02X%02X%02X",
uid[0], uid[1], uid[2], uid[3],
uid[4], uid[5], uid[5], uid[6]
);
start_time = eof_time + DELAY_ISO15693_VICC_TO_VCD_READER;
// we should do a better check than this
if (recvlen >= 12) {
uint8_t uid[8];
uid[0] = answer[9]; // always E0
uid[1] = answer[8]; // IC Manufacturer code
uid[2] = answer[7];
uid[3] = answer[6];
uid[4] = answer[5];
uid[5] = answer[4];
uid[6] = answer[3];
uid[7] = answer[2];
if (DBGLEVEL >= DBG_EXTENDED) {
Dbprintf("[+] UID = %02X%02X%02X%02X%02X%02X%02X%02X",
uid[0], uid[1], uid[2], uid[3],
uid[4], uid[5], uid[5], uid[6]
);
}
// send UID back to client.
// arg0 = 1 = OK
// arg1 = len of response (12 bytes)
// arg2 = rtf
// asbytes = uid.
reply_mix(CMD_ACK, 1, sizeof(uid), 0, uid, sizeof(uid));
if (DBGLEVEL >= DBG_EXTENDED) {
Dbprintf("[+] %d octets read from IDENTIFY request:", recvlen);
DbdecodeIso15693Answer(recvlen, answer);
Dbhexdump(recvlen, answer, true);
}
} else {
DbpString("Failed to select card");
reply_mix(CMD_ACK, 0, 0, 0, NULL, 0);
}
// send UID back to client.
// arg0 = 1 = OK
// arg1 = len of response (12 bytes)
// arg2 = rtf
// asbytes = uid.
reply_mix(CMD_ACK, 1, sizeof(uid), 0, uid, sizeof(uid));
}
if (DBGLEVEL >= DBG_EXTENDED) {
Dbprintf("[+] %d octets read from IDENTIFY request:", answerLen);
DbdecodeIso15693Answer(answerLen, answer);
Dbhexdump(answerLen, answer, true);
}
switch_off();
BigBuf_free();
}
@@ -1694,6 +1708,11 @@ void SimTagIso15693(uint8_t *uid) {
bool exit_loop = false;
while (exit_loop == false) {
button_pressed = BUTTON_PRESS();
if (button_pressed || data_available())
break;
WDT_HIT();
// find reader field
@@ -1767,6 +1786,11 @@ void BruteforceIso15693Afi(uint32_t speed) {
if (recvlen >= 12) {
Dbprintf("NoAFI UID = %s", iso15693_sprintUID(NULL, recv + 2));
} else {
DbpString("Failed to select card");
reply_ng(CMD_ACK, PM3_ESOFT, NULL, 0);
switch_off();
return;
}
// now with AFI
@@ -1816,10 +1840,9 @@ void DirectTag15693Command(uint32_t datalen, uint32_t speed, uint32_t recv, uint
LED_A_ON();
int recvlen = 0;
uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH];
uint32_t eof_time = 0;
uint16_t timeout;
uint32_t eof_time = 0;
bool request_answer = false;
switch (data[1]) {
@@ -1837,43 +1860,29 @@ void DirectTag15693Command(uint32_t datalen, uint32_t speed, uint32_t recv, uint
timeout = ISO15693_READER_TIMEOUT;
}
if (DBGLEVEL >= DBG_EXTENDED) {
Dbprintf("SEND:");
Dbhexdump(datalen, data, false);
}
uint32_t start_time = 0;
recvlen = SendDataTag(data, datalen, true, speed, (recv ? recvbuf : NULL), sizeof(recvbuf), start_time, timeout, &eof_time);
int recvlen = SendDataTag(data, datalen, true, speed, (recv ? recvbuf : NULL), sizeof(recvbuf), start_time, timeout, &eof_time);
// send a single EOF to get the tag response
if (request_answer) {
start_time = eof_time + DELAY_ISO15693_VICC_TO_VCD_READER;
recvlen = SendDataTagEOF((recv ? recvbuf : NULL), sizeof(recvbuf), start_time, ISO15693_READER_TIMEOUT, &eof_time);
if (recvlen == PM3_ETEAROFF) { // tearoff occured
reply_mix(CMD_ACK, recvlen, 0, 0, NULL, 0);
} else {
// send a single EOF to get the tag response
if (request_answer) {
start_time = eof_time + DELAY_ISO15693_VICC_TO_VCD_READER;
recvlen = SendDataTagEOF((recv ? recvbuf : NULL), sizeof(recvbuf), start_time, ISO15693_READER_TIMEOUT, &eof_time);
}
if (recv) {
recvlen = MIN(recvlen, ISO15693_MAX_RESPONSE_LENGTH);
reply_mix(CMD_ACK, recvlen, 0, 0, recvbuf, recvlen);
} else {
reply_mix(CMD_ACK, 1, 0, 0, NULL, 0);
}
}
// for the time being, switch field off to protect rdv4.0
// note: this prevents using hf 15 cmd with s option - which isn't implemented yet anyway
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LED_D_OFF();
if (recv) {
if (recvlen > ISO15693_MAX_RESPONSE_LENGTH) {
recvlen = ISO15693_MAX_RESPONSE_LENGTH;
}
reply_mix(CMD_ACK, recvlen, 0, 0, recvbuf, recvlen);
if (DBGLEVEL >= DBG_EXTENDED) {
Dbprintf("RECV:");
if (recvlen > 0) {
Dbhexdump(recvlen, recvbuf, false);
DbdecodeIso15693Answer(recvlen, recvbuf);
}
}
} else {
reply_mix(CMD_ACK, 1, 0, 0, 0, 0);
}
}
/*
+86 -15
View File
@@ -2467,7 +2467,7 @@ static uint8_t Prepare_Data(uint16_t data_low, uint16_t data_hi) {
// Requires: forwarLink_data filled with valid bits (1 bit per byte)
// fwd_bit_count set with number of bits to be sent
//====================================================================
static void SendForward(uint8_t fwd_bit_count) {
static void SendForward(uint8_t fwd_bit_count, bool fast) {
// iceman, 21.3us increments for the USclock verification.
// 55FC * 8us == 440us / 21.3 === 20.65 steps. could be too short. Go for 56FC instead
@@ -2480,9 +2480,10 @@ static void SendForward(uint8_t fwd_bit_count) {
fwd_write_ptr = forwardLink_data;
fwd_bit_sz = fwd_bit_count;
// Set up FPGA, 125kHz or 95 divisor
LFSetupFPGAForADC(LF_DIVISOR_125, true);
if (! fast) {
// Set up FPGA, 125kHz or 95 divisor
LFSetupFPGAForADC(LF_DIVISOR_125, true);
}
// force 1st mod pulse (start gap must be longer for 4305)
fwd_bit_sz--; //prepare next bit modulation
fwd_write_ptr++;
@@ -2490,28 +2491,98 @@ static void SendForward(uint8_t fwd_bit_count) {
TurnReadLF_off(EM_START_GAP);
TurnReadLFOn(18 * 8);
// now start writting with bitbanging the antenna. (each bit should be 32*8 total length)
// now start writing with bitbanging the antenna. (each bit should be 32*8 total length)
while (fwd_bit_sz-- > 0) { //prepare next bit modulation
if (((*fwd_write_ptr++) & 1) == 1) {
WaitUS(32 * 8);
} else {
TurnReadLF_off(23 * 8);
TurnReadLFOn((32 - 23) * 8);
TurnReadLFOn(18 * 8);
}
}
}
static void EM4xLogin(uint32_t pwd) {
static void EM4xLoginEx(uint32_t pwd) {
forward_ptr = forwardLink_data;
uint8_t len = Prepare_Cmd(FWD_CMD_LOGIN);
len += Prepare_Data(pwd & 0xFFFF, pwd >> 16);
SendForward(len);
SendForward(len, false);
//WaitUS(20); // no wait for login command.
// should receive
// 0000 1010 ok
// 0000 0001 fail
}
void EM4xBruteforce(uint32_t start_pwd, uint32_t n) {
// With current timing, 18.6 ms per test = 53.8 pwds/s
reply_ng(CMD_LF_EM4X_BF, PM3_SUCCESS, NULL, 0);
StartTicks();
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
WaitMS(20);
LED_A_ON();
LFSetupFPGAForADC(LF_DIVISOR_125, true);
uint32_t candidates_found = 0;
for (uint32_t pwd = start_pwd; pwd < 0xFFFFFFFF; pwd++) {
if (((pwd - start_pwd) & 0x3F) == 0x00) {
WDT_HIT();
if (BUTTON_PRESS() || data_available()) {
Dbprintf("EM4x05 Bruteforce Interrupted");
break;
}
}
// Report progress every 256 attempts
if (((pwd - start_pwd) & 0xFF) == 0x00) {
Dbprintf("Trying: %06Xxx", pwd >> 8);
}
clear_trace();
forward_ptr = forwardLink_data;
uint8_t len = Prepare_Cmd(FWD_CMD_LOGIN);
len += Prepare_Data(pwd & 0xFFFF, pwd >> 16);
SendForward(len, true);
WaitUS(400);
DoPartialAcquisition(0, false, 350, 1000);
uint8_t *mem = BigBuf_get_addr();
if (mem[334] < 128) {
candidates_found++;
Dbprintf("Password candidate: " _GREEN_("%08X"), pwd);
if ((n != 0) && (candidates_found == n)) {
Dbprintf("EM4x05 Bruteforce Stopped. %i candidate%s found", candidates_found, candidates_found > 1 ? "s" : "");
break;
}
}
// Beware: if smaller, tag might not have time to be back in listening state yet
WaitMS(1);
}
StopTicks();
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff();
}
void EM4xLogin(uint32_t pwd) {
StartTicks();
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
WaitMS(20);
LED_A_ON();
// clear buffer now so it does not interfere with timing later
BigBuf_Clear_ext(false);
EM4xLoginEx(pwd);
WaitUS(400);
// We need to acquire more than needed, to help demodulators finding the proper modulation
DoPartialAcquisition(0, false, 6000, 1000);
StopTicks();
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
reply_ng(CMD_LF_EM4X_LOGIN, PM3_SUCCESS, NULL, 0);
LEDsoff();
}
void EM4xReadWord(uint8_t addr, uint32_t pwd, uint8_t usepwd) {
StartTicks();
@@ -2529,17 +2600,17 @@ void EM4xReadWord(uint8_t addr, uint32_t pwd, uint8_t usepwd) {
* 0000 1010 ok
* 0000 0001 fail
**/
if (usepwd) EM4xLogin(pwd);
if (usepwd) EM4xLoginEx(pwd);
forward_ptr = forwardLink_data;
uint8_t len = Prepare_Cmd(FWD_CMD_READ);
len += Prepare_Addr(addr);
SendForward(len);
SendForward(len, false);
WaitUS(400);
DoPartialAcquisition(20, false, 6000, 1000);
DoPartialAcquisition(0, false, 6000, 1000);
StopTicks();
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
@@ -2564,14 +2635,14 @@ void EM4xWriteWord(uint8_t addr, uint32_t data, uint32_t pwd, uint8_t usepwd) {
* 0000 1010 ok.
* 0000 0001 fail
**/
if (usepwd) EM4xLogin(pwd);
if (usepwd) EM4xLoginEx(pwd);
forward_ptr = forwardLink_data;
uint8_t len = Prepare_Cmd(FWD_CMD_WRITE);
len += Prepare_Addr(addr);
len += Prepare_Data(data & 0xFFFF, data >> 16);
SendForward(len);
SendForward(len, false);
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occured
StopTicks();
@@ -2607,13 +2678,13 @@ void EM4xProtectWord(uint32_t data, uint32_t pwd, uint8_t usepwd) {
* 0000 1010 ok.
* 0000 0001 fail
**/
if (usepwd) EM4xLogin(pwd);
if (usepwd) EM4xLoginEx(pwd);
forward_ptr = forwardLink_data;
uint8_t len = Prepare_Cmd(FWD_CMD_PROTECT);
len += Prepare_Data(data & 0xFFFF, data >> 16);
SendForward(len);
SendForward(len, false);
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occured
StopTicks();
+2
View File
@@ -56,6 +56,8 @@ void T55xxDangerousRawTest(uint8_t *data);
void TurnReadLFOn(uint32_t delay);
void EM4xLogin(uint32_t pwd);
void EM4xBruteforce(uint32_t start_pwd, uint32_t n);
void EM4xReadWord(uint8_t addr, uint32_t pwd, uint8_t usepwd);
void EM4xWriteWord(uint8_t addr, uint32_t data, uint32_t pwd, uint8_t usepwd);
void EM4xProtectWord(uint32_t data, uint32_t pwd, uint8_t usepwd);
+9 -9
View File
@@ -2752,15 +2752,15 @@ void MifareU_Counter_Tearoff(uint8_t counter, uint32_t tearoff_time) {
// Send MFU counter increase cmd
uint8_t cmd[] = {
MIFARE_ULEV1_INCR_CNT,
counter,
0, // lsb
0,
0, // msb
0, // rfu
0,
0,
};
MIFARE_ULEV1_INCR_CNT,
counter,
0, // lsb
0,
0, // msb
0, // rfu
0,
0,
};
AddCrc14A(cmd, sizeof(cmd) - 2);
// anticollision / select card
+2 -10
View File
@@ -18,6 +18,7 @@
# -DANDROID_NATIVE_API_LEVEL=android-19 \
# -DSKIPBT=1 -DSKIPPYTHON=1 -DSKIPPTHREAD=1 ..
message(STATUS "CMake ${CMAKE_VERSION}")
cmake_minimum_required(VERSION 3.10)
project(proxmark3)
SET (PM3_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/..)
@@ -248,6 +249,7 @@ set (TARGET_SOURCES
${PM3_ROOT}/client/src/cmdlfcotag.c
${PM3_ROOT}/client/src/cmdlfdestron.c
${PM3_ROOT}/client/src/cmdlfem4x.c
${PM3_ROOT}/client/src/cmdlfem4x05.c
${PM3_ROOT}/client/src/cmdlfem4x50.c
${PM3_ROOT}/client/src/cmdlffdxb.c
${PM3_ROOT}/client/src/cmdlfgallagher.c
@@ -495,20 +497,10 @@ if (NOT APPLE)
set(ADDITIONAL_LNK ${ADDITIONAL_LNK} -Wl,--as-needed -latomic -Wl,--no-as-needed)
endif (NOT APPLE)
find_library(pm3rrg_rdv4_cliparser REQUIRED)
find_library(pm3rrg_rdv4_tinycbor REQUIRED)
find_library(pm3rrg_rdv4_lua REQUIRED)
find_library(pm3rrg_rdv4_mbedtls REQUIRED)
find_library(pm3rrg_rdv4_reveng REQUIRED)
find_library(pm3rrg_rdv4_hardnested REQUIRED)
if (NOT JANSSON_FOUND)
find_library(pm3rrg_rdv4_jansson REQUIRED)
set(ADDITIONAL_LNK pm3rrg_rdv4_jansson ${ADDITIONAL_LNK})
endif (NOT JANSSON_FOUND)
if (NOT WHEREAMI_FOUND)
find_library(pm3rrg_rdv4_whereami REQUIRED)
set(ADDITIONAL_LNK pm3rrg_rdv4_whereami ${ADDITIONAL_LNK})
endif (NOT WHEREAMI_FOUND)
+1
View File
@@ -443,6 +443,7 @@ SRCS = aidsearch.c \
cmdlfcotag.c \
cmdlfdestron.c \
cmdlfem4x.c \
cmdlfem4x05.c \
cmdlfem4x50.c \
cmdlffdxb.c \
cmdlfguard.c \
+1 -10
View File
@@ -1,4 +1,5 @@
# version
message(STATUS "CMake ${CMAKE_VERSION}")
cmake_minimum_required(VERSION 3.4.1)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3 -fvisibility=hidden -w")
@@ -12,7 +13,6 @@ add_subdirectory(../deps deps)
if (CMAKE_MAKE_PROGRAM MATCHES ".*ninja.*")
set(BZIP2_INCLUDE_DIRS ${BZIP2_ROOT})
set(BZIP2_LIBRARIES pm3rrg_rdv4_bzip2)
find_library(pm3rrg_rdv4_bzip2 REQUIRED)
elseif (UNIX) # Cross compile at Unix Makefile System.
# bzip2 dep.
include(ExternalProject)
@@ -190,15 +190,6 @@ target_include_directories(pm3rrg_rdv4 PRIVATE
${PM3_ROOT}/common_fpga
${PM3_ROOT}/client/src)
find_library(pm3rrg_rdv4_cliparser REQUIRED)
find_library(pm3rrg_rdv4_jansson REQUIRED)
find_library(pm3rrg_rdv4_tinycbor REQUIRED)
find_library(pm3rrg_rdv4_lua REQUIRED)
find_library(pm3rrg_rdv4_mbedtls REQUIRED)
find_library(pm3rrg_rdv4_reveng REQUIRED)
find_library(pm3rrg_rdv4_hardnested REQUIRED)
find_library(pm3rrg_rdv4_whereami REQUIRED)
target_link_libraries(pm3rrg_rdv4
${BZIP2_LIBRARIES}
pm3rrg_rdv4_hardnested
-1
View File
@@ -14,7 +14,6 @@ add_library(pm3rrg_rdv4_amiibo STATIC
if (NOT TARGET pm3rrg_rdv4_mbedtls)
include(mbedtls.cmake)
endif()
find_library(pm3rrg_rdv4_mbedtls REQUIRED)
target_link_libraries(pm3rrg_rdv4_amiibo PRIVATE
m
pm3rrg_rdv4_mbedtls)

Some files were not shown because too many files have changed in this diff Show More