mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-19 21:03:48 -07:00
Merge branch 'master' into master
This commit is contained in:
commit
5e277caa0b
1022 changed files with 41092 additions and 20565 deletions
12
.gitignore
vendored
12
.gitignore
vendored
|
@ -40,6 +40,7 @@ Makefile.platform
|
||||||
|
|
||||||
# cmake
|
# cmake
|
||||||
client/build/
|
client/build/
|
||||||
|
client/android/build/
|
||||||
|
|
||||||
# Coverity
|
# Coverity
|
||||||
cov-int/
|
cov-int/
|
||||||
|
@ -60,9 +61,9 @@ flasher
|
||||||
!flasher/
|
!flasher/
|
||||||
lua
|
lua
|
||||||
luac
|
luac
|
||||||
fpga_compress
|
tools/fpga_compress/fpga_compress
|
||||||
mfkey32
|
tools/mfkey/mfkey32
|
||||||
mfkey64
|
tools/mfkey/mfkey64
|
||||||
tools/nonce2key/nonce2key
|
tools/nonce2key/nonce2key
|
||||||
|
|
||||||
fpga/*
|
fpga/*
|
||||||
|
@ -87,7 +88,7 @@ client/dumps/*
|
||||||
*.ice
|
*.ice
|
||||||
*.new
|
*.new
|
||||||
armsrc/TEMP EMV/*
|
armsrc/TEMP EMV/*
|
||||||
tools/mf_nonce_brute/*
|
tools/mf_nonce_brute/mf_nonce_brute
|
||||||
tools/andrew/*
|
tools/andrew/*
|
||||||
tools/jtag_openocd/openocd_configuration
|
tools/jtag_openocd/openocd_configuration
|
||||||
ppls patches/*
|
ppls patches/*
|
||||||
|
@ -99,3 +100,6 @@ client/lualibs/pm3_cmd.lua
|
||||||
fpga_version_info.c
|
fpga_version_info.c
|
||||||
|
|
||||||
.proxmark3/*
|
.proxmark3/*
|
||||||
|
|
||||||
|
# .tmp files are created during compilation
|
||||||
|
*.tmp
|
||||||
|
|
|
@ -8,7 +8,7 @@ os:
|
||||||
- linux
|
- linux
|
||||||
- osx
|
- osx
|
||||||
|
|
||||||
dist: xenial
|
dist: bionic
|
||||||
|
|
||||||
osx_image: xcode11
|
osx_image: xcode11
|
||||||
|
|
||||||
|
@ -28,6 +28,8 @@ addons:
|
||||||
- gcc-arm-none-eabi
|
- gcc-arm-none-eabi
|
||||||
- libnewlib-dev
|
- libnewlib-dev
|
||||||
- libbluetooth-dev
|
- libbluetooth-dev
|
||||||
|
- python3-dev
|
||||||
|
- libbz2-dev
|
||||||
homebrew:
|
homebrew:
|
||||||
packages:
|
packages:
|
||||||
- readline
|
- readline
|
||||||
|
@ -54,9 +56,9 @@ install:
|
||||||
script:
|
script:
|
||||||
- if [ "$TO_TEST" = "MAKEFILE" ]; then
|
- if [ "$TO_TEST" = "MAKEFILE" ]; then
|
||||||
make clean && make V=1 "$MAKE_PARAMS";
|
make clean && make V=1 "$MAKE_PARAMS";
|
||||||
./pm3test.sh;
|
make check;
|
||||||
fi
|
fi
|
||||||
- if [ "$TO_TEST" = "CMAKE" ]; then
|
- if [ "$TO_TEST" = "CMAKE" ]; then
|
||||||
mkdir -p client/build && ( cd client/build && cmake .. && make VERBOSE=1 );
|
mkdir -p client/build && ( cd client/build && cmake .. && make VERBOSE=1 );
|
||||||
PM3BIN=./client/build/proxmark3 ./pm3test.sh client;
|
make client/check CHECKARGS="--clientbin ./client/build/proxmark3";
|
||||||
fi
|
fi
|
||||||
|
|
151
CHANGELOG.md
151
CHANGELOG.md
|
@ -3,13 +3,149 @@ All notable changes to this project will be documented in this file.
|
||||||
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
|
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
|
||||||
|
|
||||||
## [unreleased][unreleased]
|
## [unreleased][unreleased]
|
||||||
|
- Added lf em functions: 4x50_info, 4x50_write, 4x50_write_password (@tharexde)
|
||||||
|
- Fix em4x50 demodulation error (@tharexde)
|
||||||
|
- Fix `hf mfdes` authentification issues, DES working (@bkerler)
|
||||||
|
- Add Android cross-compilation to client cmake (@dxl, @doegox)
|
||||||
|
- Fix `emv scan` - now saves in current folder and uses unique names (@iceman1001)
|
||||||
|
- Fix pm3.sh - parse COM ports larger than one digit (@doegox)
|
||||||
|
- Fix stack size and automatically use available space for BigBuf. Stack is now 5K (@slurdge)
|
||||||
|
- Added Mifare MAD Card Holder Information decoding (@lukaskuzmiak)
|
||||||
|
- Change Better precision for HF and LF voltage measurements and Add theremin.py script (@rosco)
|
||||||
|
- Added Mifare MAD Info Byte decoding. Easier to identify Card Publisher (@lukaskuzmiak)
|
||||||
|
- Change use system Bzip2 library instead of Zlib for hardnested tables, tables are now 7x smaller (@doegox)
|
||||||
|
- Change pushed some ARM source to compile with THUMB. Saves a lot of space of ARM flash memory (@slurdge)
|
||||||
|
- Change from using ZLIB compression of FPGA images in ARM to LZ4. 15%+ speedups when swapping between HF & LF now (@slurdge)
|
||||||
|
- Fix `emv scan -w` - hash mismatch, solution similar to below (@iceman1001)
|
||||||
|
- Fix 'emv roca' - hash mismatch, merged from offical repo (@pwpiwi)
|
||||||
|
- Fix 'lf ti demod' - now calculates correct crc (@iceman1001)
|
||||||
|
- Add Python3 as possible script engine (@iceman1001, @doegox)
|
||||||
|
- Add doc/mfu_binary_format_notes.md (@iceman1001)
|
||||||
|
- Fix `hf mfu dump` - now reads Ulev1 3counter vs NTAG 1 counters (@iceman1001)
|
||||||
|
- Fix `hf mfu info` - now print correct cfg1 - nfc protection (@iceman1001)
|
||||||
|
- Fix `hf mfu eload` - now detects and converts between plain/old/new mfu binary format (@iceman1001)
|
||||||
|
- Change, hitag2crack now integrated into main Makefile, tests added (@doegox)
|
||||||
|
- Add `make check` mechanics (@doegox)
|
||||||
|
- Change, log files moved to subfolders (@doegox)
|
||||||
|
- Change, use system Lua library if available (@doegox)
|
||||||
|
- Change, use system Jansson library if available (@doegox)
|
||||||
|
- Change, use system Whereami library if available (@doegox)
|
||||||
|
- Change, use system Zlib library if available (@doegox)
|
||||||
|
- Fix release version information (@doegox)
|
||||||
|
|
||||||
|
## [ice coffee.4.9237][2020-05-21]
|
||||||
|
- Updated documentation (@doegox, @iceman1001)
|
||||||
|
- Change `pm3test.sh` - more regression tests to (@doegox, @iceman1001)
|
||||||
|
- Change `hf 15 dump` - now supports basic json format (@iceman1001)
|
||||||
|
- Change Test and fix many `-Wxxxxxx` warnings [compiler trials] (@doegox)
|
||||||
|
- Fix COVERITY warnings [compiler trials] (@doegox, @iceman1001)
|
||||||
|
- Fix CPPCHECKER warnings [compiler trials] (@doegox, @iceman1001)
|
||||||
|
- Fix CLANG warnings [compiler trials] (@doegox)
|
||||||
|
- Change, stricter warnings [compiler trials] (@doegox)
|
||||||
|
- Change, remove section version_information for client (@doegox)
|
||||||
|
- Change, Add RELEASE_NAME (@doegox)
|
||||||
|
- Change, version info also for client (@doegox)
|
||||||
|
- Added `make release` (@doegox)
|
||||||
|
- Change `trace load` - err if offline mode (@doegox)
|
||||||
|
- Fix `standalone mode matty_run` eloadcard (@iceman1001)
|
||||||
|
- Added, HF 15 traces (@FlUxIUS)
|
||||||
|
- Fix, follow naming conventions [android] (@dxl)
|
||||||
|
- Change, work directory supported [android] (@dxl)
|
||||||
|
- Added `lf fdx demod` - decoding of Bio-Thermo lf tag. Thanks to Rosco! (@iceman1001)
|
||||||
|
- Fix, 32-bit time_t compilation error on [WIN64] (@grspy)
|
||||||
|
- Change, LogTrace error msg (@doegox)
|
||||||
|
- Change, remove inline [compiler trials] (@iceman1001)
|
||||||
|
- Change, adding execute/home/current working directory functions to lua (<@iceman1001)
|
||||||
|
- Change, fix max duration in LogTrace (@doegox)
|
||||||
|
- Change, first attempt for trace log header (@iceman1001)
|
||||||
|
- Change, pm3.sh, attempt to detect BT dongle when udevadm is not available (@doegox)
|
||||||
|
- Change, pm3.sh, test access to /dev/ttyXXX files as prerequisite for [linux] (@doegox)
|
||||||
|
- iclass bf: avoid slowdown (@doegox)
|
||||||
|
- Change, pm3tests.sh, shellcheck (@doegox)
|
||||||
|
- Change, pm3.sh, shellcheck (@doegox)
|
||||||
|
- Change, pm3.sh, err msgs on stderr (@doegox)
|
||||||
|
- Change, pm3.sh, textual and --list with no device, exit 1 (@doegox)
|
||||||
|
- Change, pm3.sh, without udev: change detection routine (@doegox)
|
||||||
|
- Change, pm3.sh, alternative if udevadm is not available [termux] (@doegox)
|
||||||
|
- Change `makefiles` - allow to skip pthread [termux] (@doegox)
|
||||||
|
- Change `script run test_t55x7` - enabled param to swap modulation to test (@iceman1001)
|
||||||
|
- Add mf_nonce_brute from https://github.com/@iceman1001/mf_nonce_brute and merge to pm3 Makefile (@doegox)
|
||||||
|
- Change `lf indala demod` - more lenient size check (@iceman1001)
|
||||||
|
- Change clarify BUTTON macro usages (@doegox)
|
||||||
|
- Change fix REV macros & hitagS (@doegox)
|
||||||
|
- Change, `hf iclass loclass` -removed printvar function (@iceman1001)
|
||||||
|
- Change, clock can be negative (@iceman1001)
|
||||||
|
- Change `data tune` (@doegox)
|
||||||
|
- fancy timers (@doegox)
|
||||||
|
- Change, copied from pm3 repo (@iceman1001)
|
||||||
|
- Change psk demodualtion, keep starting samples to easily find the zero init bit (@iceman1001)
|
||||||
|
- Change use machine/endian.h with osx (Jamie Fiedler)
|
||||||
|
- Fix 2 issues in proxendian.h (@doegox)
|
||||||
|
- Fix issue #729. Avoid stalling on non-rdv4 when polling for FeliCa without card in proximity (@doegox)
|
||||||
|
- Change `lf nexwatch demod` - lenient demod sizes (@iceman1001)
|
||||||
|
- Change `lf nexwath sim/clone` - now supports 88bit format direct. (@iceman1001)
|
||||||
|
- Rewrited `standalone mode lf_em4100rwc `, added card bruteforce mode. (Dmitriy Loginoov)
|
||||||
|
- Change `data load` - color (@iceman1001)
|
||||||
|
- Change appveyor verbose (@doegox)
|
||||||
|
- Change `lf nexwatch demod` - now detects type, and show parity /chksum (@iceman1001)
|
||||||
|
- Change `lfsampling` - interruptible only when logging not yet triggered (@doegox)
|
||||||
|
- Change `lf keri demod - more leanient when it comes to bits (@iceman1001)
|
||||||
|
- fix, proper filtering of RL markers (@doegox)
|
||||||
|
- Change, clean deps [compiler trials] (@doegox)
|
||||||
|
- Change, remove c99 restrictions [compiler trials] (@doegox)
|
||||||
|
- Added tracelog file for hf mfu sniff or a ntag (@iceman1001)
|
||||||
|
- Change `trace list` - different alloc (@iceman1001)
|
||||||
|
- Change, convert OLD -> MIX (@iceman1001)
|
||||||
|
- Change `trace list` - adjust messages (@iceman1001)
|
||||||
|
- Fix a mem corruption in `trace load/list` (@doegox)
|
||||||
|
- Change, rework banners (@doegox)
|
||||||
|
- Change, Let's see if the prompt suffixed spaces are still needed.(@doegox)
|
||||||
|
- Fix colored readline prompt bug (@doegox)
|
||||||
|
- Change, simpler ul_print_type (@doegox)
|
||||||
|
- Fix cmake for reveng [compiler trials] (@doegox)
|
||||||
|
- Change, hook reveng outputs to pm3 machinery, add regression test (@doegox)
|
||||||
|
- Change, cmake android: add backslashes for host compatibility [compiler trials](@doegox)
|
||||||
|
- Change, Translation some comments from Chinese to English. [android] (@dxl)
|
||||||
|
- Change, cmake android: use common cmake files for deps [android] (@doegox)
|
||||||
|
- Fix, proper way to fix reveng getopt bug(@doegox)
|
||||||
|
- Change, cmake deps: add prefix pm3rrg_rdv4_ [compiler trials] (@doegox)
|
||||||
|
- Change, cmake deps: add -fPIC so they can be integrated in a pm3 shared lib [compiler trials] (@doegox)
|
||||||
|
- Change, platform adaptation [android] (@dxl)
|
||||||
|
- Change, don't mix ifdef and defined [android] (@dxl)
|
||||||
|
- fix `trace list`- too short array for explanation (@iceman1001)
|
||||||
|
- Change, check for sim module fw file (@iceman1001)
|
||||||
|
- Change, rpi aling warning [compiler trials] (@iceman1001)
|
||||||
|
- Change, more LF demodulation tests (@iceman1001)
|
||||||
|
- Change, update whereami and avoid compiling unnneded troublesome parts [compiler trials] (@doegox)
|
||||||
|
- Change, rework C includes in C++ [compiler trials] (@doegox)
|
||||||
|
- Change, leanient parsing of tcp:/bt:/socket: vars (@iceman1001)
|
||||||
|
- Change, add bluetooth group to `make accessrights` (@iceman1001)
|
||||||
|
- Change, `Makefile` - fix PKG_CONFIG_ENV (@uli)
|
||||||
|
- Change, `f sim` - now only fills until bigbuffer is full (@iceman1001)
|
||||||
|
- Change, `hf mf hardnested` - don't drop field when in test mode (@doegox)
|
||||||
|
- Change, `lf sim` - better to return err on faulty offset, thanks @iceman (@doegox)
|
||||||
|
- Change, `lf sim` - fix offset of last packet (@doegox)
|
||||||
|
- Change, `client Makefile` - make sure to rebuild deps when needed [compiler trials](@doegox)
|
||||||
|
- Change, silent err if dbus absent [linux] (@doegox)
|
||||||
|
- Change, `pm3.sh` - for direct bt devices (@doegox)
|
||||||
|
- Change, `pm3.sh` - moved WSL/PS3.x bt native to be tested first. Since call to Win32_serialport crashes it. (@iceman1001)
|
||||||
|
- Change, `pm3.sh` - Bt dongle, bt direct listing of serial ports on WSL and PS3.x, now using powershell.exe since wmic is deprecated (@iceman1001)
|
||||||
|
- Change, remove libsndfile (@doegox)
|
||||||
|
- Change, enforce PACKED structs [compiler trials] (@iceman1001)
|
||||||
|
- Change, adjust number of threads according to cpu (@iceman1001)
|
||||||
|
- Change, `hitag2crack` compile flags(@doegox)
|
||||||
|
- Change, msdsal fix bug after var de-shadowing (@doegox)
|
||||||
|
- Change, lighter msg for loading prefs, json will anyway always tell the filename (@doegox)
|
||||||
|
- Change, make sure colors and emoji are disabled when not on TTY (@doegox)
|
||||||
|
- Added `pref` command. PM3 client now support user preferences saved to a json file. (@mwalker33)
|
||||||
|
- Added native support for Bluetooth in client [linux] (@doegox)
|
||||||
- Added `LF_EM4100RSWB` (based on `LF_EM4100RWC`) standalone mode to read/sim/clone/brute EM4100 cards (@Monster1024)
|
- Added `LF_EM4100RSWB` (based on `LF_EM4100RWC`) standalone mode to read/sim/clone/brute EM4100 cards (@Monster1024)
|
||||||
- Added `HF_MSDSAL` standalone mode which read and emulate Visa EMV cards (@Netxing)
|
- Added `HF_MSDSAL` standalone mode which read and emulate Visa EMV cards (@Netxing)
|
||||||
- Added Mifare Ultralight tear off experiment (@cintainfinita and @fukmar)
|
- Added `hf mfu tear` - Mifare Ultralight tear off experiment (@cintainfinitam, @fukmar)
|
||||||
- Added Mifare Desfire Read/Write/Create files/records/values functionality and several fixes to `hf mfdes` (@bkerler)
|
- Added Mifare Desfire Read/Write/Create files/records/values functionality and several fixes to `hf mfdes` (@bkerler)
|
||||||
- Added CreateStdFile command to Mifare `hf mfdes` (@bkerler)
|
- Added CreateStdFile command to Mifare `hf mfdes` (@bkerler)
|
||||||
- Rework des/3des/3k3des/aes auth. Port to mbedtls crypto library on device (@bkerler)
|
- Rework des/3des/3k3des/aes auth. Port to mbedtls crypto library on device (@bkerler)
|
||||||
- Port 'hf mfdes' Authentification to CommandNG structure, fix auth session key (@bkerler)
|
- Port `hf mfdes` Authentification to CommandNG structure, fix auth session key (@bkerler)
|
||||||
- Updates `hf mfdes` functions, improved logging and added new commands (@bkerler)
|
- Updates `hf mfdes` functions, improved logging and added new commands (@bkerler)
|
||||||
- Updated 'legic.lua' and 'legic_clone.lua' script - works with current command set (@Pizza_4u)
|
- Updated 'legic.lua' and 'legic_clone.lua' script - works with current command set (@Pizza_4u)
|
||||||
- Rewrote `hf mfdes` functions and added apdu debugging (@bkerler)
|
- Rewrote `hf mfdes` functions and added apdu debugging (@bkerler)
|
||||||
|
@ -18,10 +154,11 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
|
||||||
- Improved `hf 14a info` - card detection handling (@bkerler)
|
- Improved `hf 14a info` - card detection handling (@bkerler)
|
||||||
- Updated helptext layout in all luascripts (@iceman1001)
|
- Updated helptext layout in all luascripts (@iceman1001)
|
||||||
- Change `hf mfdes info` - output and logging (@bkerler)
|
- Change `hf mfdes info` - output and logging (@bkerler)
|
||||||
- Updated texts in legic commands (@ikarus23)
|
- Updated texts in `hf legic` commands (@ikarus23)
|
||||||
- Fix timing bug inside 40x5 (@mwalker33)
|
- Fix timing bug inside 40x5 (@mwalker33)
|
||||||
- Refactored all Hitag2 attacks (@doegox)
|
- Refactored all Hitag2 attacks (@doegox)
|
||||||
- Added two new Hitag2 attacks (@doegox)
|
- Added two new Hitag2 attacks (@doegox)
|
||||||
|
- Change `hf iclass decrypt` - limit amount of data to read if wrong app limit (@iceman1001)
|
||||||
- Change `hf search` - now continue to search in case of dual tech cards (@iceman1001) Thanks to @ikarus23 for the suggestion!
|
- Change `hf search` - now continue to search in case of dual tech cards (@iceman1001) Thanks to @ikarus23 for the suggestion!
|
||||||
- Added `hf topas info` - old reader command, now also prints NDEF (@iceman1001)
|
- Added `hf topas info` - old reader command, now also prints NDEF (@iceman1001)
|
||||||
- Change `hf topaz reader` - now only prints lighter info, like UID. (@iceman1001)
|
- Change `hf topaz reader` - now only prints lighter info, like UID. (@iceman1001)
|
||||||
|
@ -40,14 +177,14 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
|
||||||
- Change - NDEF supports more signatures now (@iceman1001)
|
- Change - NDEF supports more signatures now (@iceman1001)
|
||||||
- OSX Makefile now supports `make style` and `make checks` (@Pizza_4u)
|
- OSX Makefile now supports `make style` and `make checks` (@Pizza_4u)
|
||||||
- Added `HF_LEGIC` standalone mode to read and simulate a Legic prime tag (@Pizza_4u)
|
- Added `HF_LEGIC` standalone mode to read and simulate a Legic prime tag (@Pizza_4u)
|
||||||
- Added keri MS decode/encode and update 'lf keri clone' to support MS fc/cid cloning. (@mwalker33)
|
- Added keri MS decode/encode and update `lf keri clone` to support MS fc/cid cloning. (@mwalker33)
|
||||||
- Fix 'hf mfdes enum' - now actually manages to enumerate files under all AID's. :smiley: (@iceman1001)
|
- Fix `hf mfdes enum` - now actually manages to enumerate files under all AID's. :smiley: (@iceman1001)
|
||||||
- Fix 'hf mfdes info' - now detects DESFire light and work properly Wrapped commands :+1: (@iceman1001)
|
- Fix `hf mfdes info` - now detects DESFire light and work properly Wrapped commands :+1: (@iceman1001)
|
||||||
- :smiling_imp: support (@doegox)
|
- :smiling_imp: support (@doegox)
|
||||||
- Additional colour changes as recommended by @iceman (@dunderhay)
|
- Additional colour changes as recommended by @iceman (@dunderhay)
|
||||||
- Change type colour for `hf 14a` card types (@dunderhay)
|
- Change type colour for `hf 14a` card types (@dunderhay)
|
||||||
- Add colour to `hf mfdes` command (@dunderhay)
|
- Add colour to `hf mfdes` command (@dunderhay)
|
||||||
- Add 'HINTS' command. Will turn off / on hint messages. Default mode is OFF. (@iceman1001)
|
- Add `HINTS` command. Will turn off / on hint messages. Default mode is OFF. (@iceman1001)
|
||||||
- Add colour to `hf 14a` and `hf mfu` commands (@dunderhay)
|
- Add colour to `hf 14a` and `hf mfu` commands (@dunderhay)
|
||||||
- Add colour to `lf hid` commands (@dunderhay)
|
- Add colour to `lf hid` commands (@dunderhay)
|
||||||
- Change `script run hf_bruteforce -s start_id -e end_id -t timeout -x mifare_card_type` - The hf_bruteforce card script now requires Mifare type (mfc or mfu) (@dunderhay)
|
- Change `script run hf_bruteforce -s start_id -e end_id -t timeout -x mifare_card_type` - The hf_bruteforce card script now requires Mifare type (mfc or mfu) (@dunderhay)
|
||||||
|
|
94
Makefile
94
Makefile
|
@ -14,7 +14,9 @@ ifneq (,$(DESTDIR))
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
all clean install uninstall: %: client/% bootrom/% armsrc/% recovery/% mfkey/% nonce2key/% fpga_compress/%
|
all clean install uninstall check: %: client/% bootrom/% armsrc/% recovery/% mfkey/% nonce2key/% mf_nonce_brute/% fpga_compress/%
|
||||||
|
# hitag2crack toolsuite is not yet integrated in "all", it must be called explicitly: "make hitag2crack"
|
||||||
|
#all clean install uninstall check: %: hitag2crack/%
|
||||||
|
|
||||||
INSTALLTOOLS=pm3_eml2lower.sh pm3_eml2upper.sh pm3_mfdread.py pm3_mfd2eml.py pm3_eml2mfd.py findbits.py rfidtest.pl xorcheck.py
|
INSTALLTOOLS=pm3_eml2lower.sh pm3_eml2upper.sh pm3_mfdread.py pm3_mfd2eml.py pm3_eml2mfd.py findbits.py rfidtest.pl xorcheck.py
|
||||||
INSTALLSIMFW=sim011.bin sim011.sha512.txt
|
INSTALLSIMFW=sim011.bin sim011.sha512.txt
|
||||||
|
@ -78,12 +80,49 @@ ifeq ($(platform),Linux)
|
||||||
endif
|
endif
|
||||||
$(Q)$(RMDIR_SOFT) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH)
|
$(Q)$(RMDIR_SOFT) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH)
|
||||||
|
|
||||||
|
# tests
|
||||||
|
mfkey/check: FORCE
|
||||||
|
$(info [*] CHECK $(patsubst %/check,%,$@))
|
||||||
|
$(Q)$(BASH) tools/pm3_tests.sh $(CHECKARGS) $(patsubst %/check,%,$@)
|
||||||
|
nonce2key/check: FORCE
|
||||||
|
$(info [*] CHECK $(patsubst %/check,%,$@))
|
||||||
|
$(Q)$(BASH) tools/pm3_tests.sh $(CHECKARGS) $(patsubst %/check,%,$@)
|
||||||
|
mf_nonce_brute/check: FORCE
|
||||||
|
$(info [*] CHECK $(patsubst %/check,%,$@))
|
||||||
|
$(Q)$(BASH) tools/pm3_tests.sh $(CHECKARGS) $(patsubst %/check,%,$@)
|
||||||
|
fpga_compress/check: FORCE
|
||||||
|
$(info [*] CHECK $(patsubst %/check,%,$@))
|
||||||
|
$(Q)$(BASH) tools/pm3_tests.sh $(CHECKARGS) $(patsubst %/check,%,$@)
|
||||||
|
bootrom/check: FORCE
|
||||||
|
$(info [*] CHECK $(patsubst %/check,%,$@))
|
||||||
|
$(Q)$(BASH) tools/pm3_tests.sh $(CHECKARGS) $(patsubst %/check,%,$@)
|
||||||
|
armsrc/check: FORCE
|
||||||
|
$(info [*] CHECK $(patsubst %/check,%,$@))
|
||||||
|
$(Q)$(BASH) tools/pm3_tests.sh $(CHECKARGS) $(patsubst %/check,%,$@)
|
||||||
|
client/check: FORCE
|
||||||
|
$(info [*] CHECK $(patsubst %/check,%,$@))
|
||||||
|
$(Q)$(BASH) tools/pm3_tests.sh $(CHECKARGS) $(patsubst %/check,%,$@)
|
||||||
|
recovery/check: FORCE
|
||||||
|
$(info [*] CHECK $(patsubst %/check,%,$@))
|
||||||
|
$(Q)$(BASH) tools/pm3_tests.sh $(CHECKARGS) $(patsubst %/check,%,$@)
|
||||||
|
hitag2crack/check: FORCE
|
||||||
|
$(info [*] CHECK $(patsubst %/check,%,$@))
|
||||||
|
$(Q)$(BASH) tools/pm3_tests.sh $(CHECKARGS) $(patsubst %/check,%,$@)
|
||||||
|
common/check: FORCE
|
||||||
|
$(info [*] CHECK $(patsubst %/check,%,$@))
|
||||||
|
$(Q)$(BASH) tools/pm3_tests.sh $(CHECKARGS) $(patsubst %/check,%,$@)
|
||||||
|
check: common/check
|
||||||
|
$(info [*] ALL CHECKS DONE)
|
||||||
|
|
||||||
mfkey/%: FORCE
|
mfkey/%: FORCE
|
||||||
$(info [*] MAKE $@)
|
$(info [*] MAKE $@)
|
||||||
$(Q)$(MAKE) --no-print-directory -C tools/mfkey $(patsubst mfkey/%,%,$@) DESTDIR=$(MYDESTDIR)
|
$(Q)$(MAKE) --no-print-directory -C tools/mfkey $(patsubst mfkey/%,%,$@) DESTDIR=$(MYDESTDIR)
|
||||||
nonce2key/%: FORCE
|
nonce2key/%: FORCE
|
||||||
$(info [*] MAKE $@)
|
$(info [*] MAKE $@)
|
||||||
$(Q)$(MAKE) --no-print-directory -C tools/nonce2key $(patsubst nonce2key/%,%,$@) DESTDIR=$(MYDESTDIR)
|
$(Q)$(MAKE) --no-print-directory -C tools/nonce2key $(patsubst nonce2key/%,%,$@) DESTDIR=$(MYDESTDIR)
|
||||||
|
mf_nonce_brute/%: FORCE
|
||||||
|
$(info [*] MAKE $@)
|
||||||
|
$(Q)$(MAKE) --no-print-directory -C tools/mf_nonce_brute $(patsubst mf_nonce_brute/%,%,$@) DESTDIR=$(MYDESTDIR)
|
||||||
fpga_compress/%: FORCE
|
fpga_compress/%: FORCE
|
||||||
$(info [*] MAKE $@)
|
$(info [*] MAKE $@)
|
||||||
$(Q)$(MAKE) --no-print-directory -C tools/fpga_compress $(patsubst fpga_compress/%,%,$@) DESTDIR=$(MYDESTDIR)
|
$(Q)$(MAKE) --no-print-directory -C tools/fpga_compress $(patsubst fpga_compress/%,%,$@) DESTDIR=$(MYDESTDIR)
|
||||||
|
@ -101,9 +140,12 @@ recovery/install: bootrom/all armsrc/all
|
||||||
recovery/%: FORCE cleanifplatformchanged
|
recovery/%: FORCE cleanifplatformchanged
|
||||||
$(info [*] MAKE $@)
|
$(info [*] MAKE $@)
|
||||||
$(Q)$(MAKE) --no-print-directory -C recovery $(patsubst recovery/%,%,$@) DESTDIR=$(MYDESTDIR)
|
$(Q)$(MAKE) --no-print-directory -C recovery $(patsubst recovery/%,%,$@) DESTDIR=$(MYDESTDIR)
|
||||||
|
hitag2crack/%: FORCE
|
||||||
|
$(info [*] MAKE $@)
|
||||||
|
$(Q)$(MAKE) --no-print-directory -C tools/hitag2crack $(patsubst hitag2crack/%,%,$@) DESTDIR=$(MYDESTDIR)
|
||||||
FORCE: # Dummy target to force remake in the subdirectories, even if files exist (this Makefile doesn't know about the prerequisites)
|
FORCE: # Dummy target to force remake in the subdirectories, even if files exist (this Makefile doesn't know about the prerequisites)
|
||||||
|
|
||||||
.PHONY: all clean install uninstall help _test bootrom fullimage recovery client mfkey nonce2key style checks FORCE udev accessrights cleanifplatformchanged
|
.PHONY: all clean install uninstall help _test bootrom fullimage recovery client mfkey nonce2key mf_nonce_brute hitag2crack style miscchecks release FORCE udev accessrights cleanifplatformchanged
|
||||||
|
|
||||||
help:
|
help:
|
||||||
@echo "Multi-OS Makefile"
|
@echo "Multi-OS Makefile"
|
||||||
|
@ -122,10 +164,14 @@ help:
|
||||||
@echo "+ client - Make only the OS-specific host client"
|
@echo "+ client - Make only the OS-specific host client"
|
||||||
@echo "+ mfkey - Make tools/mfkey"
|
@echo "+ mfkey - Make tools/mfkey"
|
||||||
@echo "+ nonce2key - Make tools/nonce2key"
|
@echo "+ nonce2key - Make tools/nonce2key"
|
||||||
|
@echo "+ mf_nonce_brute - Make tools/mf_nonce_brute"
|
||||||
|
@echo "+ hitag2crack - Make tools/hitag2crack"
|
||||||
@echo "+ fpga_compress - Make tools/fpga_compress"
|
@echo "+ fpga_compress - Make tools/fpga_compress"
|
||||||
@echo
|
@echo
|
||||||
@echo "+ style - Apply some automated source code formatting rules"
|
@echo "+ style - Apply some automated source code formatting rules"
|
||||||
@echo "+ checks - Detect various encoding issues in source code"
|
@echo "+ check - Run offline tests. Set CHECKARGS to pass arguments to the test script"
|
||||||
|
@echo "+ .../check - Run offline tests against specific target. See above."
|
||||||
|
@echo "+ miscchecks - Detect various encoding issues in source code"
|
||||||
@echo
|
@echo
|
||||||
@echo "Possible platforms: try \"make PLATFORM=\" for more info, default is PM3RDV4"
|
@echo "Possible platforms: try \"make PLATFORM=\" for more info, default is PM3RDV4"
|
||||||
@echo "To activate verbose mode, use make V=1"
|
@echo "To activate verbose mode, use make V=1"
|
||||||
|
@ -152,8 +198,12 @@ mfkey: mfkey/all
|
||||||
|
|
||||||
nonce2key: nonce2key/all
|
nonce2key: nonce2key/all
|
||||||
|
|
||||||
|
mf_nonce_brute: mf_nonce_brute/all
|
||||||
|
|
||||||
fpga_compress: fpga_compress/all
|
fpga_compress: fpga_compress/all
|
||||||
|
|
||||||
|
hitag2crack: hitag2crack/all
|
||||||
|
|
||||||
newtarbin:
|
newtarbin:
|
||||||
$(RM) proxmark3-$(platform)-bin.tar proxmark3-$(platform)-bin.tar.gz
|
$(RM) proxmark3-$(platform)-bin.tar proxmark3-$(platform)-bin.tar.gz
|
||||||
@touch proxmark3-$(platform)-bin.tar
|
@touch proxmark3-$(platform)-bin.tar
|
||||||
|
@ -164,7 +214,7 @@ tarbin: newtarbin client/tarbin armsrc/tarbin bootrom/tarbin
|
||||||
|
|
||||||
# detect if there were changes in the platform definitions, requiring a clean
|
# detect if there were changes in the platform definitions, requiring a clean
|
||||||
cleanifplatformchanged:
|
cleanifplatformchanged:
|
||||||
ifeq ($(PLATFORM_CHANGED), true)
|
ifeq ($(PLATFORM_CHANGED),true)
|
||||||
$(info [!] Platform definitions changed, cleaning bootrom/armsrc/recovery first...)
|
$(info [!] Platform definitions changed, cleaning bootrom/armsrc/recovery first...)
|
||||||
$(Q)$(MAKE) --no-print-directory -C bootrom clean
|
$(Q)$(MAKE) --no-print-directory -C bootrom clean
|
||||||
$(Q)$(MAKE) --no-print-directory -C armsrc clean
|
$(Q)$(MAKE) --no-print-directory -C armsrc clean
|
||||||
|
@ -211,7 +261,7 @@ style:
|
||||||
--align-pointer=name {} \;
|
--align-pointer=name {} \;
|
||||||
|
|
||||||
# Detecting weird codepages and tabs.
|
# Detecting weird codepages and tabs.
|
||||||
checks:
|
miscchecks:
|
||||||
# Make sure recode is installed
|
# Make sure recode is installed
|
||||||
@which recode >/dev/null || ( echo "Please install 'recode' package first" ; exit 1 )
|
@which recode >/dev/null || ( echo "Please install 'recode' package first" ; exit 1 )
|
||||||
@echo "Files with suspicious chars:"
|
@echo "Files with suspicious chars:"
|
||||||
|
@ -230,5 +280,39 @@ endif
|
||||||
# @find . \( -name "*.[ch]" -or \( -name "*.cpp" -and -not -name "*.moc.cpp" \) -or -name "*.lua" -or -name "*.py" -or -name "*.pl" -or -name "*.md" -or -name "*.txt" -or -name "*.awk" -or -name "*.v" \) \
|
# @find . \( -name "*.[ch]" -or \( -name "*.cpp" -and -not -name "*.moc.cpp" \) -or -name "*.lua" -or -name "*.py" -or -name "*.pl" -or -name "*.md" -or -name "*.txt" -or -name "*.awk" -or -name "*.v" \) \
|
||||||
# -exec grep -lP '\\t' {} \;
|
# -exec grep -lP '\\t' {} \;
|
||||||
|
|
||||||
|
release: VERSION="v4.$(shell git log --oneline master | wc -l)"
|
||||||
|
release:
|
||||||
|
$(if $(findstring master,$(shell git rev-parse --abbrev-ref HEAD)),,$(error "!!! you are not on master branch, aborting"))
|
||||||
|
$(if $(findstring dirty,$(shell git describe --dirty --always)),$(error "!!! you have pending changes, aborting"))
|
||||||
|
$(if $(RELEASE_NAME),,$(error "!!! missing RELEASE_NAME, aborting"))
|
||||||
|
# Preparing a commit for release tagging, to be reverted after tagging.
|
||||||
|
@echo "# - Release Tag: $(VERSION)"
|
||||||
|
@echo "# - Release Name: $(RELEASE_NAME)"
|
||||||
|
# - Removing -Werror...
|
||||||
|
@find . \( -path "./Makefile.defs" -or -path "./client/Makefile" -or -path "./common_arm/Makefile.common" -or -path "./tools/hitag2crack/*/Makefile" \) -exec sed -i 's/ -Werror//' {} \;
|
||||||
|
@find . \( -path "./client/deps/*.cmake" -or -path "./client/CMakeLists.txt" \) -exec sed -i 's/ -Werror//' {} \;
|
||||||
|
# - Changing banner...
|
||||||
|
@sed -i "s/^#define BANNERMSG3 .*/#define BANNERMSG3 \"Release $(VERSION) - $(RELEASE_NAME)\"/" client/src/proxmark3.c
|
||||||
|
@echo -n "# ";grep "^#define BANNERMSG3" client/src/proxmark3.c
|
||||||
|
# - Committing temporarily...
|
||||||
|
@git commit -a -m "Release $(VERSION) - $(RELEASE_NAME)"
|
||||||
|
# - Tagging temporarily...
|
||||||
|
@git tag -a -m "Release $(VERSION) - $(RELEASE_NAME)" $(VERSION)
|
||||||
|
# - Changing default version information based on new tag
|
||||||
|
@$(SH) tools/mkversion.sh > common/default_version.c.tmp && $(MV) common/default_version.c.tmp common/default_version.c
|
||||||
|
# - Removing mkversion calls
|
||||||
|
@sed -i 's#^.*\.\./tools/mkversion.sh.*|| #\t$$(Q)#' client/Makefile bootrom/Makefile armsrc/Makefile
|
||||||
|
@sed -i '/COMMAND/s/sh .*|| //' client/CMakeLists.txt
|
||||||
|
# - Deleting tag...
|
||||||
|
@git tag -d $(VERSION)
|
||||||
|
# - Amending commit...
|
||||||
|
@git commit -a --amend -m "Release $(VERSION) - $(RELEASE_NAME)"
|
||||||
|
# - Tagging again...
|
||||||
|
@git tag -a -m "Release $(VERSION) - $(RELEASE_NAME)" $(VERSION)
|
||||||
|
# - Reverting tagged commit...
|
||||||
|
@git revert --no-edit HEAD
|
||||||
|
@echo "==================================================================="
|
||||||
|
@echo "Done! You can now execute 'git push && git push origin $(VERSION)'"
|
||||||
|
|
||||||
# Dummy target to test for GNU make availability
|
# Dummy target to test for GNU make availability
|
||||||
_test:
|
_test:
|
||||||
|
|
|
@ -24,6 +24,9 @@ CROSS ?= arm-none-eabi-
|
||||||
CC = gcc
|
CC = gcc
|
||||||
CXX = g++
|
CXX = g++
|
||||||
LD = g++
|
LD = g++
|
||||||
|
SH = sh
|
||||||
|
BASH = bash
|
||||||
|
PERL = perl
|
||||||
|
|
||||||
PATHSEP=/
|
PATHSEP=/
|
||||||
PREFIX ?= /usr/local
|
PREFIX ?= /usr/local
|
||||||
|
@ -63,6 +66,7 @@ endif
|
||||||
EXTRACFLAGS =
|
EXTRACFLAGS =
|
||||||
EXTRACFLAGS += -Wunused-parameter -Wno-error=unused-parameter
|
EXTRACFLAGS += -Wunused-parameter -Wno-error=unused-parameter
|
||||||
EXTRACFLAGS += -Wsign-compare -Wno-error=sign-compare
|
EXTRACFLAGS += -Wsign-compare -Wno-error=sign-compare
|
||||||
|
EXTRACFLAGS += -Wconversion -Wno-error=conversion -Wno-error=sign-conversion -Wno-error=float-conversion
|
||||||
|
|
||||||
# unknown to clang or old gcc:
|
# unknown to clang or old gcc:
|
||||||
# First we activate Wextra then we explicitly list those we know about
|
# First we activate Wextra then we explicitly list those we know about
|
||||||
|
|
|
@ -17,6 +17,8 @@ endif
|
||||||
|
|
||||||
CFLAGS ?= $(DEFCFLAGS)
|
CFLAGS ?= $(DEFCFLAGS)
|
||||||
CFLAGS += $(MYDEFS) $(MYCFLAGS) $(MYINCLUDES)
|
CFLAGS += $(MYDEFS) $(MYCFLAGS) $(MYINCLUDES)
|
||||||
|
LDFLAGS += $(MYLDFLAGS)
|
||||||
|
LDLIBS += $(MYLDLIBS)
|
||||||
|
|
||||||
vpath %.c $(MYSRCPATHS)
|
vpath %.c $(MYSRCPATHS)
|
||||||
|
|
||||||
|
@ -66,7 +68,7 @@ $(BINDIR)/$(LIB_A): $(MYOBJS)
|
||||||
|
|
||||||
$(BINDIR)/% : $(OBJDIR)/%.o $(MYOBJS) $(MYLIBS)
|
$(BINDIR)/% : $(OBJDIR)/%.o $(MYOBJS) $(MYLIBS)
|
||||||
$(info [=] LD $(notdir $@))
|
$(info [=] LD $(notdir $@))
|
||||||
$(Q)$(LD) $(LDFLAGS) $(MYOBJS) $< -o $@ $(MYLIBS)
|
$(Q)$(LD) $(LDFLAGS) $(MYOBJS) $< -o $@ $(MYLIBS) $(MYLDLIBS)
|
||||||
|
|
||||||
$(OBJDIR)/%.o : %.c | $(OBJDIR)
|
$(OBJDIR)/%.o : %.c | $(OBJDIR)
|
||||||
$(info [-] CC $<)
|
$(info [-] CC $<)
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
# Run 'make PLATFORM=' to get an exhaustive list of possible parameters for this file.
|
# Run 'make PLATFORM=' to get an exhaustive list of possible parameters for this file.
|
||||||
|
|
||||||
PLATFORM=PM3RDV4
|
PLATFORM=PM3RDV4
|
||||||
|
#PLATFORM=PM3OTHER
|
||||||
# If you want more than one PLATFORM_EXTRAS option, separate them by spaces:
|
# If you want more than one PLATFORM_EXTRAS option, separate them by spaces:
|
||||||
#PLATFORM_EXTRAS=BTADDON
|
#PLATFORM_EXTRAS=BTADDON
|
||||||
#STANDALONE=LF_SAMYRUN
|
#STANDALONE=HF_MSDSAL
|
||||||
STANDALONE=LF_ICEHID
|
|
||||||
|
|
99
README.md
99
README.md
|
@ -1,9 +1,11 @@
|
||||||
# RRG / Iceman repo - Proxmark3
|
# RRG / Iceman repo - Proxmark3
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
| Releases | Linux & OSX CI | Windows CI | Coverity |
|
| Releases | Linux & OSX CI | Windows CI | Coverity |
|
||||||
| ------------------- |:-------------------:| -------------------:| -------------------:|
|
| ------------------- |:-------------------:| -------------------:| -------------------:|
|
||||||
| [](https://github.com/RfidResearchGroup/proxmark3/releases/latest) | [](https://travis-ci.org/RfidResearchGroup/proxmark3) | [](https://ci.appveyor.com/project/RfidResearchGroup/proxmark3/branch/master) | [](https://scan.coverity.com/projects/proxmark3-rrg-iceman-repo)|
|
| [](https://github.com/RfidResearchGroup/proxmark3/releases/latest) | [](https://travis-ci.org/RfidResearchGroup/proxmark3) | [](https://ci.appveyor.com/project/RfidResearchGroup/proxmark3/branch/master) | [](https://scan.coverity.com/projects/proxmark3-rrg-iceman-repo)|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -16,15 +18,22 @@
|
||||||
|[Why didn't you base it on official Proxmark3 Master?](#why-didnt-you-base-it-on-official-proxmark3-master)| **[Homebrew (Mac OS X) & Upgrading HomeBrew Tap Formula](/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md)** | [First Use and Verification](/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md)|
|
|[Why didn't you base it on official Proxmark3 Master?](#why-didnt-you-base-it-on-official-proxmark3-master)| **[Homebrew (Mac OS X) & Upgrading HomeBrew Tap Formula](/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md)** | [First Use and Verification](/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md)|
|
||||||
|[Proxmark3 GUI](#proxmark3-gui)|**[Setup and build for Windows](/doc/md/Installation_Instructions/Windows-Installation-Instructions.md)**|[Commands & Features](/doc/md/Use_of_Proxmark/3_Commands-and-Features.md)|
|
|[Proxmark3 GUI](#proxmark3-gui)|**[Setup and build for Windows](/doc/md/Installation_Instructions/Windows-Installation-Instructions.md)**|[Commands & Features](/doc/md/Use_of_Proxmark/3_Commands-and-Features.md)|
|
||||||
|[Issues](#issues)|[Blue shark manual](/doc/bt_manual_v10.md) ||
|
|[Issues](#issues)|[Blue shark manual](/doc/bt_manual_v10.md) ||
|
||||||
|[Notes on UART](/doc/uart_notes.md)|[Maintainers](/doc/md/Development/Maintainers.md)|[Command Cheat sheet](/doc/cheatsheet.md)|
|
|[Donations](#Donations)|[Maintainers](/doc/md/Development/Maintainers.md)|[Command Cheat sheet](/doc/cheatsheet.md)|
|
||||||
|[Notes on frame format](/doc/new_frame_format.md)|[Advanced compilation parameters](/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md)|[More cheat sheets](https://github.com/RfidResearchGroup/proxmark3/wiki/More-cheat-sheets)|
|
||[Advanced compilation parameters](/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md)|[More cheat sheets](https://github.com/RfidResearchGroup/proxmark3/wiki/More-cheat-sheets)|
|
||||||
|[Notes on external flash](/doc/ext_flash_notes.md)||[EMV](/doc/emv_notes.md)|
|
||**[Troubleshooting](/doc/md/Installation_Instructions/Troubleshooting.md)**|[Complete client command set](/doc/commands.md)|
|
||||||
|[Notes on Termux / Android](/doc/termux_notes.md)|**[Troubleshooting](/doc/md/Installation_Instructions/Troubleshooting.md)**|[Complete client command set](/doc/commands.md)|
|
||**[JTAG](/doc/jtag_notes.md)**||
|
||||||
|[Notes on tracedata / wireshark](/doc/trace_notes.md)|**[JTAG](/doc/jtag_notes.md)**||
|
|
||||||
|[Notes on loclass](/doc/loclass_notes.md)|||
|
|
||||||
|[Notes on paths](/doc/path_notes.md)|||
|
## Notes / helpful documents
|
||||||
|[Developing standalone mode](/armsrc/Standalone/readme.md)|[Wiki about standalone mode](https://github.com/RfidResearchGroup/proxmark3/wiki/Standalone-mode) ||
|
|
||||||
|[Donations](#Donations)|||
|
| Notes |||
|
||||||
|
| ------------------- |:-------------------:| -------------------:|
|
||||||
|
|[Notes on UART](/doc/uart_notes.md)|[Notes on Termux / Android](/doc/termux_notes.md)|[Notes on paths](/doc/path_notes.md)|
|
||||||
|
|[Notes on frame format](/doc/new_frame_format.md)|[Notes on tracelog / wireshark](/doc/trace_notes.md)|[Notes on EMV](/doc/emv_notes.md)|
|
||||||
|
|[Notes on external flash](/doc/ext_flash_notes.md)|[Notes on loclass](/doc/loclass_notes.md)|[Notes on Coverity Scan Config & Run](/doc/md/Development/Coverity-Scan-Config-%26-Run.md)|
|
||||||
|
|[Notes on file formats used with Proxmark3](/doc/extensions_notes.md)|[Notes on MFU binary format](/doc/mfu_binary_format_notes.md)|[Notes on FPGA & ARM](/doc/fpga_arm_notes.md)|
|
||||||
|
|[Developing standalone mode](/armsrc/Standalone/readme.md)|[Wiki about standalone mode](https://github.com/RfidResearchGroup/proxmark3/wiki/Standalone-mode)||
|
||||||
|
|[Notes on Color usage](/doc/colors_notes.md)||
|
||||||
|
|
||||||
|
|
||||||
## Build for non-RDV4 Proxmark3 platforms
|
## Build for non-RDV4 Proxmark3 platforms
|
||||||
|
@ -48,30 +57,63 @@ On the software side: quite a lot, see the [Changelog file](CHANGELOG.md).
|
||||||
|
|
||||||
This repo compiles nicely on
|
This repo compiles nicely on
|
||||||
- Proxspace v3.x
|
- Proxspace v3.x
|
||||||
- Windows/mingw environment with Qt5.6.1 & GCC 4.8
|
- [latest release v3.4](https://github.com/Gator96100/ProxSpace/releases)
|
||||||
- Ubuntu 1604, 1804, 1904
|
- Windows/mingw environment with Qt5.6.1 & GCC 4.9
|
||||||
|
- Ubuntu 1604 -> 2004
|
||||||
|
- ParrotOS, Gentoo, Pentoo, Kali, Nethunter, Archlinux, Fedora, Debian
|
||||||
|
- Rasbian
|
||||||
|
- Android / Termux
|
||||||
- Mac OS X / Homebrew
|
- Mac OS X / Homebrew
|
||||||
- ParrotOS, Gentoo, Pentoo, Kali, Nethunter, Archlinux, Fedora
|
|
||||||
- WSL, WSL2 (Windows subsystem linux) on Windows 10
|
- WSL, WSL2 (Windows subsystem linux) on Windows 10
|
||||||
- Docker container
|
- Docker container
|
||||||
|
- [ RRG / Iceman repo based ubuntu 18.04 container ](https://hub.docker.com/r/secopsconsult/proxmark3)
|
||||||
|
- [ Iceman fork based container v1.7 ](https://hub.docker.com/r/iceman1001/proxmark3/)
|
||||||
|
|
||||||
|
Hardware to run client on
|
||||||
|
- PC
|
||||||
|
- Android
|
||||||
|
- Raspberry Pi & Raspberry Pi Zero
|
||||||
|
- Jetson Nano
|
||||||
|
|
||||||
|
## Precompiled binaries
|
||||||
|
We don't maintain any precompiled binaries in this repo. There is community effort over at the Proxmark3 forum where @gator96100 has set up a google drive with many mingw binaries which is up-to-date. We link to these files here as to make it easier for users.
|
||||||
|
If you are having troubles with these files, contact the package maintainer @gator96100 and read the [sticky thread at forum](http://www.proxmark.org/forum/viewtopic.php?pid=24763#p24763) where known issues has been documented.
|
||||||
|
|
||||||
|
|
||||||
|
Ref:
|
||||||
|
|
||||||
|
- [Precompiled builds for RDV40 dedicated x86](https://drive.google.com/open?id=13zUs-aiQkYaSl5KWrBtuW5IWCoHJPsue)
|
||||||
|
- [Precompiled builds for RDV40 dedicated x64](https://drive.google.com/open?id=1SyPB8t5Vo8O0Lh7PjNm3Kv-mO4BNbxjX)
|
||||||
|
|
||||||
|
- [Precompiled builds for RDV40 dedicated with Bluetooth addon x86](https://drive.google.com/open?id=1TqWYctkRvkLshQ1ZRBHPLDzYHR-asuMO)
|
||||||
|
- [Precompiled builds for RDV40 dedicated with Bluetooth addon x64](https://drive.google.com/open?id=17ful7u2QyYmMQzQzc5fAf8nJvyoDJfSL)
|
||||||
|
|
||||||
|
Generice Proxmark3 devices (non RDV4)
|
||||||
|
- [Precompiled builds for RRG / Iceman repository x86](https://drive.google.com/open?id=1PI3Xr1mussPBPnYGu4ZjWzGPARK4N7JR)
|
||||||
|
- [Precompiled builds for RRG / Iceman repository x64](https://drive.google.com/open?id=1uX9RtYGinuFrpHybu4xq_BE3HrobI20e)
|
||||||
|
|
||||||
|
|
||||||
|
## Roadmap
|
||||||
The [public roadmap](https://github.com/RfidResearchGroup/proxmark3/wiki/Public-Roadmap) is an excellent start to read if you are interesting in contributing.
|
The [public roadmap](https://github.com/RfidResearchGroup/proxmark3/wiki/Public-Roadmap) is an excellent start to read if you are interesting in contributing.
|
||||||
|
|
||||||
> 👉 **Remember!** If you intend to contribute to the code, please read the [coding style notes](HACKING.md) first.
|
> 👉 **Remember!** If you intend to contribute to the code, please read the [coding style notes](HACKING.md) first.
|
||||||
We usually merge your contributions fast since we do like the idea of getting a functionality in the Proxmark3 and weed out the bugs afterwards.
|
We usually merge your contributions fast since we do like the idea of getting a functionality in the Proxmark3 and weed out the bugs afterwards.
|
||||||
|
|
||||||
## Notes / helpful documents
|
|
||||||
- notes on [Coverity Scan Config & Run](/doc/md/Development/Coverity-Scan-Config-%26-Run.md).
|
## Issues & Troubleshooting
|
||||||
- notes on [UART](/doc/uart_notes.md)
|
Please search the [issues](https://github.com/rfidresearchgroup/proxmark3/issues) page here and see if your issue is listed in the first instance. Next place to visit is the [Proxmark Forum](http://www.proxmark.org/forum/index.php). Learn to search it well and finally Google / duckduckgo is your friend :) You will find many blogposts, youtube videos, tweets, reddit
|
||||||
- notes on [Frame format](/doc/new_frame_format.md)
|
|
||||||
- notes on [external flash](/doc/ext_flash_notes.md)
|
Read the [Troubleshooting](/doc/md/Installation_Instructions/Troubleshooting.md) guide to weed out most known problems.
|
||||||
- notes on [standalone mode](https://github.com/RfidResearchGroup/proxmark3/wiki/Standalone-mode)
|
|
||||||
- notes on [Termux / Android](/doc/termux_notes.md)
|
Offical channels
|
||||||
- notes on [tracedata / Wireshark](/doc/trace_notes.md)
|
- [Proxmark3 IRC channel](http://webchat.freenode.net/?channels=#proxmark3)
|
||||||
- notes on [loclass](/doc/loclass_notes.md)
|
- [Proxmark3 sub reddit](https://www.reddit.com/r/proxmark3/)
|
||||||
- notes on [EMV](/doc/emv_notes.md)
|
- [Twitter](https://twitter.com/proxmark3/)
|
||||||
- notes on [Paths](/doc/path_notes.md)
|
|
||||||
- notes on [file formats used with Proxmark3](/doc/extensions_notes.md)
|
_no discord or slack channel_
|
||||||
|
|
||||||
|
Iceman has quite a few videos on his [youtube channel](https://www.youtube.com/c/ChrisHerrmann1001)
|
||||||
|
|
||||||
## Cheat sheet
|
## Cheat sheet
|
||||||
|
|
||||||
Thanks to Alex Dibs, you can enjoy a [command cheat sheet](/doc/cheatsheet.md)
|
Thanks to Alex Dibs, you can enjoy a [command cheat sheet](/doc/cheatsheet.md)
|
||||||
|
@ -90,13 +132,6 @@ The separation from official Proxmark3 repo gives us a lot of freedom to create
|
||||||
The official PM3-GUI from Gaucho will not work.
|
The official PM3-GUI from Gaucho will not work.
|
||||||
The new universal GUI will work. [Proxmark3 Universal GUI](https://github.com/burma69/PM3UniversalGUI) Almost, change needed in order to show helptext when client isn't connected to a device.
|
The new universal GUI will work. [Proxmark3 Universal GUI](https://github.com/burma69/PM3UniversalGUI) Almost, change needed in order to show helptext when client isn't connected to a device.
|
||||||
|
|
||||||
## Issues
|
|
||||||
|
|
||||||
Please see the [Proxmark Forum](http://www.proxmark.org/forum/index.php) and see if your issue is listed in the first instance Google is your friend :) Questions will be answered via the forum by Iceman and the team.
|
|
||||||
|
|
||||||
Read the [Troubleshooting](/doc/md/Installation_Instructions/Troubleshooting.md) guide to weed out most known problems.
|
|
||||||
|
|
||||||
|
|
||||||
## The end
|
## The end
|
||||||
|
|
||||||
- July 2018 [@herrmann1001](https://mobile.twitter.com/herrmann1001)
|
- July 2018 [@herrmann1001](https://mobile.twitter.com/herrmann1001)
|
||||||
|
|
268
appveyor.yml
268
appveyor.yml
|
@ -1,5 +1,5 @@
|
||||||
version: 3.0.1.{build}
|
version: 3.0.1.{build}
|
||||||
image: Visual Studio 2017
|
image: Visual Studio 2019
|
||||||
clone_folder: C:\ProxSpace\pm3
|
clone_folder: C:\ProxSpace\pm3
|
||||||
init:
|
init:
|
||||||
- ps: >-
|
- ps: >-
|
||||||
|
@ -7,7 +7,6 @@ init:
|
||||||
|
|
||||||
#Get-ChildItem Env:
|
#Get-ChildItem Env:
|
||||||
|
|
||||||
|
|
||||||
$releasename=""
|
$releasename=""
|
||||||
|
|
||||||
$env:APPVEYOR_REPO_COMMIT_SHORT = $env:APPVEYOR_REPO_COMMIT.Substring(0, 8)
|
$env:APPVEYOR_REPO_COMMIT_SHORT = $env:APPVEYOR_REPO_COMMIT.Substring(0, 8)
|
||||||
|
@ -23,11 +22,12 @@ init:
|
||||||
|
|
||||||
Add-AppveyorMessage -Message "[$env:APPVEYOR_REPO_COMMIT_SHORT]$env:appveyor_repo_name($env:APPVEYOR_REPO_BRANCH)" -Category Information -Details "repository: $env:appveyor_repo_name branch: $env:APPVEYOR_REPO_BRANCH release: $releasename"
|
Add-AppveyorMessage -Message "[$env:APPVEYOR_REPO_COMMIT_SHORT]$env:appveyor_repo_name($env:APPVEYOR_REPO_BRANCH)" -Category Information -Details "repository: $env:appveyor_repo_name branch: $env:APPVEYOR_REPO_BRANCH release: $releasename"
|
||||||
|
|
||||||
|
|
||||||
# iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
# iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
||||||
clone_script:
|
clone_script:
|
||||||
- ps: >-
|
- ps: >-
|
||||||
Write-Host "Removing ProxSpace..." -NoNewLine
|
Write-Host "Removing ProxSpace..." -NoNewLine
|
||||||
|
|
||||||
|
$CloneTime=[System.Environment]::TickCount
|
||||||
|
|
||||||
cd \
|
cd \
|
||||||
|
|
||||||
|
@ -152,24 +152,15 @@ clone_script:
|
||||||
|
|
||||||
ExecUpdate "update2" "C:\ProxSpace\msys2\msys2_shell.cmd -mingw32 -defterm -no-start /dev/null" "terminate?MSYS2"
|
ExecUpdate "update2" "C:\ProxSpace\msys2\msys2_shell.cmd -mingw32 -defterm -no-start /dev/null" "terminate?MSYS2"
|
||||||
|
|
||||||
|
Add-AppveyorMessage -Message "ProxSpace download and update took $(([System.Environment]::TickCount-$CloneTime) / 1000) sec" -Category Information
|
||||||
|
|
||||||
Write-Host "Update " -NoNewLine
|
Write-Host "Update " -NoNewLine
|
||||||
|
|
||||||
Write-Host "[ OK ]" -ForegroundColor Green
|
Write-Host "[ OK ]" -ForegroundColor Green
|
||||||
install:
|
install:
|
||||||
- ps: >-
|
|
||||||
function Exec-External {
|
|
||||||
param(
|
|
||||||
[Parameter(Position=0,Mandatory=1)][scriptblock] $command
|
|
||||||
)
|
|
||||||
& $command
|
|
||||||
if ($LASTEXITCODE -ne 0) {
|
|
||||||
throw ("Command returned non-zero error-code ${LASTEXITCODE}: $command")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
build_script:
|
build_script:
|
||||||
- ps: >-
|
- ps: >-
|
||||||
"C:\ProxSpace\msys2\usr\bin;C:\ProxSpace\msys2\mingw32\bin;C:\ProxSpace\gcc-arm-none-eabi\bin;$env:Path"
|
$env:Path="C:\ProxSpace\msys2\usr\bin;C:\ProxSpace\msys2\mingw32\bin;C:\ProxSpace\gcc-arm-none-eabi\bin;c:\Python38;c:\Python38\Scripts;$env:Path"
|
||||||
|
|
||||||
|
|
||||||
$env:MINGW_HOME="C:\ProxSpace\msys2\mingw32"
|
$env:MINGW_HOME="C:\ProxSpace\msys2\mingw32"
|
||||||
|
|
||||||
|
@ -185,9 +176,13 @@ build_script:
|
||||||
|
|
||||||
cd C:\ProxSpace\pm3
|
cd C:\ProxSpace\pm3
|
||||||
|
|
||||||
|
Write-Host "---------- make ----------" -ForegroundColor Yellow
|
||||||
|
|
||||||
|
$TestTime=[System.Environment]::TickCount
|
||||||
|
|
||||||
#make
|
#make
|
||||||
|
|
||||||
bash -c -i 'pwd;make clean;make V=1'
|
bash -c -i 'echo $PATH;pwd;make clean;make V=1'
|
||||||
|
|
||||||
|
|
||||||
#some checks
|
#some checks
|
||||||
|
@ -198,206 +193,75 @@ build_script:
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!(Test-Path C:\ProxSpace\pm3\armsrc\obj\fullimage.elf)){
|
cd c:\ProxSpace\pm3
|
||||||
|
|
||||||
throw "ARM file fullimage.elf not exists."
|
bash -c -i 'make check'
|
||||||
|
|
||||||
|
$testspass = ($LASTEXITCODE -eq 0)
|
||||||
|
|
||||||
|
$global:TestsPassed=$testspass
|
||||||
|
|
||||||
|
if ($testspass) {
|
||||||
|
Add-AppveyorTest -Name "make Tests" -Framework NUnit -Filename "make check" -Outcome Passed -Duration "$([System.Environment]::TickCount-$TestTime)"
|
||||||
|
Write-Host "make Tests [ OK ]" -ForegroundColor Green
|
||||||
|
} else {
|
||||||
|
Add-AppveyorTest -Name "make Tests" -Framework NUnit -Filename "make check" -Outcome Failed -Duration "$([System.Environment]::TickCount-$TestTime)"
|
||||||
|
Write-Host "make Tests [ ERROR ]" -ForegroundColor Red
|
||||||
|
throw "Tests error."
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Write-Host "---------- btaddon ----------" -ForegroundColor Yellow
|
||||||
|
|
||||||
|
$TestTime=[System.Environment]::TickCount
|
||||||
|
|
||||||
if(!(Test-Path C:\ProxSpace\pm3\client\resources\hardnested_tables\*.bin.z)){
|
bash -c -i 'pwd;make clean;make PLATFORM_EXTRAS=BTADDON'
|
||||||
|
|
||||||
throw "Files in client\resources\hardnested_tables is not exists."
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#install
|
|
||||||
|
|
||||||
Write-Host "Installing..." -NoNewLine -ForegroundColor Yellow
|
|
||||||
|
|
||||||
New-Item -ItemType Directory -Force -Path C:\ProxSpace\pm3\Release\bin
|
|
||||||
|
|
||||||
bash -c -i 'make install DESTDIR=Release PREFIX='
|
|
||||||
|
|
||||||
# dll files
|
|
||||||
|
|
||||||
Copy-Item C:\ProxSpace\msys2\mingw32\bin\libgcc_s_dw2-1.dll C:\ProxSpace\pm3\Release\bin
|
|
||||||
|
|
||||||
Copy-Item C:\ProxSpace\msys2\mingw32\bin\libstdc++-6.dll C:\ProxSpace\pm3\Release\bin
|
|
||||||
|
|
||||||
Copy-Item C:\ProxSpace\msys2\mingw32\bin\libwinpthread-1.dll C:\ProxSpace\pm3\Release\bin
|
|
||||||
|
|
||||||
Copy-Item C:\ProxSpace\msys2\mingw32\bin\Qt5Core.dll C:\ProxSpace\pm3\Release\bin
|
|
||||||
|
|
||||||
Copy-Item C:\ProxSpace\msys2\mingw32\bin\Qt5Gui.dll C:\ProxSpace\pm3\Release\bin
|
|
||||||
|
|
||||||
Copy-Item C:\ProxSpace\msys2\mingw32\bin\Qt5Widgets.dll C:\ProxSpace\pm3\Release\bin
|
|
||||||
|
|
||||||
Copy-Item C:\ProxSpace\msys2\mingw32\bin\libreadline*.dll C:\ProxSpace\pm3\Release\bin
|
|
||||||
|
|
||||||
Copy-Item C:\ProxSpace\msys2\mingw32\bin\libtermcap-0.dll C:\ProxSpace\pm3\Release\bin
|
|
||||||
|
|
||||||
Write-Host "[ OK ]" -ForegroundColor Green
|
|
||||||
|
|
||||||
|
|
||||||
#archive and push
|
|
||||||
|
|
||||||
$releasename=""
|
|
||||||
|
|
||||||
if ($env:appveyor_repo_tag -match "true"){
|
|
||||||
|
|
||||||
$releasename=$env:APPVEYOR_REPO_TAG_NAME + "/"
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
$releasename+=$env:APPVEYOR_BUILD_VERSION + " [" + $env:APPVEYOR_REPO_COMMIT.Substring(0, 7) + "]"
|
|
||||||
|
|
||||||
|
|
||||||
Write-Host "Archive and publish release files ($releasename)..." -NoNewLine -ForegroundColor Yellow
|
|
||||||
|
|
||||||
cd C:\ProxSpace
|
|
||||||
|
|
||||||
7z a release.zip C:\ProxSpace\pm3\Release
|
|
||||||
|
|
||||||
Push-AppveyorArtifact release.zip -DeploymentName "$releasename"
|
|
||||||
|
|
||||||
Write-Host "[ OK ]" -ForegroundColor Green
|
|
||||||
|
|
||||||
|
|
||||||
Write-Host "Builded..." -ForegroundColor Yellow
|
|
||||||
test_script:
|
|
||||||
- ps: >-
|
|
||||||
$env:Path = "C:\ProxSpace\msys\bin;$env:Path"
|
|
||||||
|
|
||||||
cd c:\ProxSpace\pm3
|
cd c:\ProxSpace\pm3
|
||||||
|
|
||||||
|
bash -c -i 'make check'
|
||||||
|
|
||||||
$global:TestsPassed=$true
|
$testspass = ($LASTEXITCODE -eq 0)
|
||||||
|
|
||||||
|
$global:TestsPassed=(($global:TestsPassed) -and ($testspass))
|
||||||
Function ExecTest($Name, $File, $Cmd, $CheckResult) {
|
|
||||||
|
|
||||||
#--- begin Job
|
if ($testspass) {
|
||||||
|
Add-AppveyorTest -Name "BTaddon Tests" -Framework NUnit -Filename "make check" -Outcome Passed -Duration "$([System.Environment]::TickCount-$TestTime)"
|
||||||
$Job = Start-Job -ScriptBlock {
|
Write-Host "BTaddon Tests [ OK ]" -ForegroundColor Green
|
||||||
[bool]$res=$false
|
} else {
|
||||||
$TestTime=[System.Environment]::TickCount
|
Add-AppveyorTest -Name "BTaddon Tests" -Framework NUnit -Filename "make check" -Outcome Failed -Duration "$([System.Environment]::TickCount-$TestTime)"
|
||||||
$env:Path = "C:\ProxSpace\msys\bin;$env:Path"
|
Write-Host "BTaddon Tests [ ERROR ]" -ForegroundColor Red
|
||||||
Set-Location $using:PWD
|
|
||||||
|
|
||||||
$sb=[scriptblock]::Create("$using:Cmd")
|
|
||||||
#execute scriptblock
|
|
||||||
Write-host "Test [$using:Name] job: $using:Cmd"
|
|
||||||
$Cond=&$sb
|
|
||||||
|
|
||||||
if ($Cond -eq $null){
|
|
||||||
} ElseIf($using:CheckResult -ne $null) {
|
|
||||||
[String]$searchstr=""
|
|
||||||
if ($Cond -is [Object]){
|
|
||||||
ForEach($line in $Cond){
|
|
||||||
Write-host $line -ForegroundColor Gray
|
|
||||||
$searchstr += $line
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
Write-host "$Cond" -ForegroundColor Gray
|
|
||||||
$searchstr = $Cond
|
|
||||||
}
|
|
||||||
If($searchstr -like "*$using:CheckResult*") {
|
|
||||||
$res=$true
|
|
||||||
}
|
|
||||||
$Cond="*$using:CheckResult*"
|
|
||||||
} Else {
|
|
||||||
If (!($Cond -is [bool] -or $Cond -is [byte] -or $Cond -is [int16] -or $Cond -is [int32] -or $Cond -is [int64] -or $Cond -is [float])){
|
|
||||||
if ($Cond -is "String" -and $Cond -like "*passed*"){
|
|
||||||
$res= $true
|
|
||||||
}
|
|
||||||
if ($Cond -is "String" -and $Cond -like "*true*"){
|
|
||||||
$res= $true
|
|
||||||
}
|
|
||||||
ForEach($line in $Cond){
|
|
||||||
if ($line -like "*passed*"){
|
|
||||||
$res = $true
|
|
||||||
$Cond = $line
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} Else {
|
|
||||||
$res=$Cond
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
If ($res) {
|
|
||||||
Write-host "Result[$using:Name]: $Cond" -ForegroundColor Green
|
|
||||||
Add-AppveyorTest -Name "$using:Name" -Framework NUnit -Filename "$using:File" -Outcome Passed -Duration "$([System.Environment]::TickCount-$TestTime)"
|
|
||||||
}Else {
|
|
||||||
Write-host "Result[$using:Name]: $Cond" -ForegroundColor Red
|
|
||||||
Add-AppveyorTest -Name "$using:Name" -Framework NUnit -Filename "$using:File" -Outcome Failed -Duration "$([System.Environment]::TickCount-$TestTime)" -ErrorMessage "command:$using:Cmd`nresult:$Cond"
|
|
||||||
}
|
|
||||||
return $res
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Write-Host "---------- make clean ----------" -ForegroundColor Yellow
|
||||||
|
|
||||||
|
bash -c -i 'make clean'
|
||||||
|
|
||||||
|
Write-Host "---------- cmake ----------" -ForegroundColor Yellow
|
||||||
|
|
||||||
|
$TestTime=[System.Environment]::TickCount
|
||||||
|
|
||||||
#--- end Job
|
cmd.exe /c 'C:\ProxSpace\msys2\msys2_shell.cmd -mingw32 -defterm -no-start -c "mkdir -p client/build; cd client/build; cmake -G""MSYS Makefiles"" ..; make VERBOSE=1;"'
|
||||||
|
|
||||||
|
Write-Host "---------- cmake tests ----------" -ForegroundColor Yellow
|
||||||
|
|
||||||
[bool]$res=$false
|
cd c:\ProxSpace\pm3
|
||||||
# Wait 180 sec timeout for Job
|
|
||||||
if(Wait-Job $Job -Timeout 180){
|
|
||||||
$Results = $Job | Receive-Job
|
|
||||||
if($Results -like "true"){
|
|
||||||
$res=$true
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Write-host "Test [$Name] timeout" -ForegroundColor Red
|
|
||||||
Add-AppveyorTest -Name "$Name" -Framework NUnit -Filename "$File" -Outcome Failed -Duration 60000 -ErrorMessage "timeout"
|
|
||||||
}
|
|
||||||
Remove-Job -Force $Job
|
|
||||||
|
|
||||||
if(!$res){
|
bash -c -i './tools/pm3_tests.sh --clientbin client/build/proxmark3.exe client'
|
||||||
Write-host "--------------------- tests fail" -ForegroundColor Red
|
|
||||||
$global:TestsPassed=$false
|
$testspass = ($LASTEXITCODE -eq 0)
|
||||||
}
|
|
||||||
|
$global:TestsPassed=(($global:TestsPassed) -and ($testspass))
|
||||||
|
|
||||||
|
if ($testspass) {
|
||||||
|
Add-AppveyorTest -Name "cmake Tests" -Framework NUnit -Filename "make client/check" -Outcome Passed -Duration "$([System.Environment]::TickCount-$TestTime)"
|
||||||
|
Write-Host "cmake Tests [ OK ]" -ForegroundColor Green
|
||||||
|
} else {
|
||||||
|
Add-AppveyorTest -Name "cmake Tests" -Framework NUnit -Filename "make client/check" -Outcome Failed -Duration "$([System.Environment]::TickCount-$TestTime)"
|
||||||
|
Write-Host "cmake Tests [ ERROR ]" -ForegroundColor Red
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test_script:
|
||||||
Write-Host "Running tests..." -ForegroundColor Yellow
|
- ps: >-
|
||||||
|
|
||||||
|
|
||||||
#file test
|
|
||||||
|
|
||||||
ExecTest "proxmark3 exists" "proxmark3.exe" {Test-Path C:\ProxSpace\pm3\Release\bin\proxmark3.exe}
|
|
||||||
|
|
||||||
ExecTest "arm bootrom exists" "bootrom.elf" {Test-Path C:\ProxSpace\pm3\Release\share\proxmark3\firmware\bootrom.elf}
|
|
||||||
|
|
||||||
ExecTest "arm image exists" "fullimage.elf" {Test-Path C:\ProxSpace\pm3\Release\share\proxmark3\firmware\fullimage.elf}
|
|
||||||
|
|
||||||
ExecTest "arm recovery image exists" "proxmark3_recovery.bin" {Test-Path C:\ProxSpace\pm3\Release\share\proxmark3\firmware\proxmark3_recovery.bin}
|
|
||||||
|
|
||||||
ExecTest "hardnested tables exists" "hardnested" {Test-Path C:\ProxSpace\pm3\Release\share\proxmark3\resources\hardnested_tables\*.z}
|
|
||||||
|
|
||||||
ExecTest "release exists" "release.zip" {Test-Path C:\ProxSpace\release.zip}
|
|
||||||
|
|
||||||
|
|
||||||
#proxmark logic tests
|
|
||||||
|
|
||||||
ExecTest "proxmark help" "proxmark3 -h" {bash -lc 'cd ~/client;./proxmark3 -h 2>&1 | grep -q wait && echo passed || echo failed'}
|
|
||||||
|
|
||||||
ExecTest "proxmark help text ISO7816" "proxmark3 -t" {bash -lc 'cd ~/client;./proxmark3 -t 2>&1 | grep -q ISO7816 && echo passed || echo failed'}
|
|
||||||
|
|
||||||
ExecTest "proxmark help text hardnested" "proxmark3 -t" {bash -lc 'cd ~/client;./proxmark3 -t 2>&1 | grep -q hardnested && echo passed || echo failed'}
|
|
||||||
|
|
||||||
|
|
||||||
ExecTest "hf mf offline text" "hf mf" {bash -lc "cd ~/client;./proxmark3 -c 'hf mf'"} "at_enc"
|
|
||||||
|
|
||||||
#proxmark crypto tests
|
|
||||||
|
|
||||||
# Long tests:
|
|
||||||
# ExecTest "hf mf hardnested" "hf mf hardnested" {bash -lc "cd ~/client;./proxmark3 -c 'hf mf hardnested t 1 000000000000'"} "found:"
|
|
||||||
# ExecTest "hf mf iclass" "hf mf iclass" {bash -lc "cd ~/client;./proxmark3 -c 'hf iclass loclass t l'"} "verified ok"
|
|
||||||
# ExecTest "emv test" "emv test" {bash -lc "cd ~/client;./proxmark3 -c 'emv test -i -l'"} "Test?s? ? OK"
|
|
||||||
# Short tests:
|
|
||||||
ExecTest "hf mf iclass" "hf mf iclass" {bash -lc "cd ~/client;./proxmark3 -c 'hf iclass loclass t'"} "OK!"
|
|
||||||
ExecTest "emv test" "emv test" {bash -lc "cd ~/client;./proxmark3 -c 'emv test -i'"} "Test?s? ? OK"
|
|
||||||
|
|
||||||
|
|
||||||
if ($global:TestsPassed) {
|
if ($global:TestsPassed) {
|
||||||
Write-Host "Tests [ OK ]" -ForegroundColor Green
|
Write-Host "Tests [ OK ]" -ForegroundColor Green
|
||||||
} else {
|
} else {
|
||||||
|
@ -409,4 +273,4 @@ on_success:
|
||||||
on_failure:
|
on_failure:
|
||||||
- ps: Write-Host "Build error." -ForegroundColor Red
|
- ps: Write-Host "Build error." -ForegroundColor Red
|
||||||
on_finish:
|
on_finish:
|
||||||
- ps: # $blockRdp = $false; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
- ps: # $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
||||||
|
|
|
@ -12,35 +12,50 @@
|
||||||
|
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include "dbprint.h"
|
#include "dbprint.h"
|
||||||
|
#include "pm3_cmd.h"
|
||||||
|
|
||||||
|
extern uint8_t _stack_start, __bss_end__;
|
||||||
|
|
||||||
// BigBuf is the large multi-purpose buffer, typically used to hold A/D samples or traces.
|
// BigBuf is the large multi-purpose buffer, typically used to hold A/D samples or traces.
|
||||||
// Also used to hold various smaller buffers and the Mifare Emulator Memory.
|
// Also used to hold various smaller buffers and the Mifare Emulator Memory.
|
||||||
// declare it as uint32_t to achieve alignment to 4 Byte boundary
|
// We know that bss is aligned to 4 bytes.
|
||||||
static uint32_t BigBuf[BIGBUF_SIZE / sizeof(uint32_t)];
|
static uint8_t *BigBuf = &__bss_end__;
|
||||||
|
|
||||||
/* BigBuf memory layout:
|
/* BigBuf memory layout:
|
||||||
Pointer to highest available memory: BigBuf_hi
|
Pointer to highest available memory: BigBuf_hi
|
||||||
|
high BigBuf_size
|
||||||
high BIGBUF_SIZE
|
|
||||||
reserved = BigBuf_malloc() subtracts amount from BigBuf_hi,
|
reserved = BigBuf_malloc() subtracts amount from BigBuf_hi,
|
||||||
low 0x00
|
low 0x00
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static uint32_t BigBuf_size = 0;
|
||||||
|
|
||||||
// High memory mark
|
// High memory mark
|
||||||
static uint16_t BigBuf_hi = BIGBUF_SIZE;
|
static uint32_t BigBuf_hi = 0;
|
||||||
|
|
||||||
// pointer to the emulator memory.
|
// pointer to the emulator memory.
|
||||||
static uint8_t *emulator_memory = NULL;
|
static uint8_t *emulator_memory = NULL;
|
||||||
|
|
||||||
// trace related variables
|
// trace related variables
|
||||||
static uint32_t traceLen = 0;
|
static uint32_t traceLen = 0;
|
||||||
static bool tracing = true; //todo static?
|
static bool tracing = true;
|
||||||
|
|
||||||
|
// compute the available size for BigBuf
|
||||||
|
void BigBuf_initialize(void) {
|
||||||
|
BigBuf_size = (uint32_t)&_stack_start - (uint32_t)&__bss_end__;
|
||||||
|
BigBuf_hi = BigBuf_size;
|
||||||
|
traceLen = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// get the address of BigBuf
|
// get the address of BigBuf
|
||||||
uint8_t *BigBuf_get_addr(void) {
|
uint8_t *BigBuf_get_addr(void) {
|
||||||
return (uint8_t *)BigBuf;
|
return (uint8_t *)BigBuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t BigBuf_get_size(void) {
|
||||||
|
return BigBuf_size;
|
||||||
|
}
|
||||||
|
|
||||||
// get the address of the emulator memory. Allocate part of Bigbuf for it, if not yet done
|
// get the address of the emulator memory. Allocate part of Bigbuf for it, if not yet done
|
||||||
uint8_t *BigBuf_get_EM_addr(void) {
|
uint8_t *BigBuf_get_EM_addr(void) {
|
||||||
// not yet allocated
|
// not yet allocated
|
||||||
|
@ -57,9 +72,9 @@ void BigBuf_Clear(void) {
|
||||||
|
|
||||||
// clear ALL of BigBuf
|
// clear ALL of BigBuf
|
||||||
void BigBuf_Clear_ext(bool verbose) {
|
void BigBuf_Clear_ext(bool verbose) {
|
||||||
memset(BigBuf, 0, BIGBUF_SIZE);
|
memset(BigBuf, 0, BigBuf_size);
|
||||||
if (verbose)
|
if (verbose)
|
||||||
Dbprintf("Buffer cleared (%i bytes)", BIGBUF_SIZE);
|
Dbprintf("Buffer cleared (%i bytes)", BigBuf_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BigBuf_Clear_EM(void) {
|
void BigBuf_Clear_EM(void) {
|
||||||
|
@ -73,7 +88,7 @@ void BigBuf_Clear_keep_EM(void) {
|
||||||
// allocate a chunk of memory from BigBuf. We allocate high memory first. The unallocated memory
|
// allocate a chunk of memory from BigBuf. We allocate high memory first. The unallocated memory
|
||||||
// at the beginning of BigBuf is always for traces/samples
|
// at the beginning of BigBuf is always for traces/samples
|
||||||
uint8_t *BigBuf_malloc(uint16_t chunksize) {
|
uint8_t *BigBuf_malloc(uint16_t chunksize) {
|
||||||
if (BigBuf_hi - chunksize < 0)
|
if (BigBuf_hi < chunksize)
|
||||||
return NULL; // no memory left
|
return NULL; // no memory left
|
||||||
|
|
||||||
chunksize = (chunksize + 3) & 0xfffc; // round to next multiple of 4
|
chunksize = (chunksize + 3) & 0xfffc; // round to next multiple of 4
|
||||||
|
@ -83,7 +98,7 @@ uint8_t *BigBuf_malloc(uint16_t chunksize) {
|
||||||
|
|
||||||
// free ALL allocated chunks. The whole BigBuf is available for traces or samples again.
|
// free ALL allocated chunks. The whole BigBuf is available for traces or samples again.
|
||||||
void BigBuf_free(void) {
|
void BigBuf_free(void) {
|
||||||
BigBuf_hi = BIGBUF_SIZE;
|
BigBuf_hi = BigBuf_size;
|
||||||
emulator_memory = NULL;
|
emulator_memory = NULL;
|
||||||
// shouldn't this empty BigBuf also?
|
// shouldn't this empty BigBuf also?
|
||||||
}
|
}
|
||||||
|
@ -93,16 +108,16 @@ void BigBuf_free_keep_EM(void) {
|
||||||
if (emulator_memory != NULL)
|
if (emulator_memory != NULL)
|
||||||
BigBuf_hi = emulator_memory - (uint8_t *)BigBuf;
|
BigBuf_hi = emulator_memory - (uint8_t *)BigBuf;
|
||||||
else
|
else
|
||||||
BigBuf_hi = BIGBUF_SIZE;
|
BigBuf_hi = BigBuf_size;
|
||||||
|
|
||||||
// shouldn't this empty BigBuf also?
|
// shouldn't this empty BigBuf also?
|
||||||
}
|
}
|
||||||
|
|
||||||
void BigBuf_print_status(void) {
|
void BigBuf_print_status(void) {
|
||||||
DbpString(_BLUE_("Memory"));
|
DbpString(_CYAN_("Memory"));
|
||||||
Dbprintf(" BIGBUF_SIZE.............%d", BIGBUF_SIZE);
|
Dbprintf(" BigBuf_size.............%d", BigBuf_size);
|
||||||
Dbprintf(" Available memory........%d", BigBuf_hi);
|
Dbprintf(" Available memory........%d", BigBuf_hi);
|
||||||
DbpString(_BLUE_("Tracing"));
|
DbpString(_CYAN_("Tracing"));
|
||||||
Dbprintf(" tracing ................%d", tracing);
|
Dbprintf(" tracing ................%d", tracing);
|
||||||
Dbprintf(" traceLen ...............%d", traceLen);
|
Dbprintf(" traceLen ...............%d", traceLen);
|
||||||
}
|
}
|
||||||
|
@ -146,41 +161,37 @@ bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_
|
||||||
if (!tracing) return false;
|
if (!tracing) return false;
|
||||||
|
|
||||||
uint8_t *trace = BigBuf_get_addr();
|
uint8_t *trace = BigBuf_get_addr();
|
||||||
|
tracelog_hdr_t *hdr = (tracelog_hdr_t *)(trace + traceLen);
|
||||||
|
|
||||||
uint32_t num_paritybytes = (iLen - 1) / 8 + 1; // number of valid paritybytes in *parity
|
uint32_t num_paritybytes = (iLen - 1) / 8 + 1; // number of valid paritybytes in *parity
|
||||||
uint32_t duration = timestamp_end - timestamp_start;
|
|
||||||
|
|
||||||
// Return when trace is full
|
// Return when trace is full
|
||||||
if (traceLen + sizeof(iLen) + sizeof(timestamp_start) + sizeof(duration) + num_paritybytes + iLen >= BigBuf_max_traceLen()) {
|
if (TRACELOG_HDR_LEN + iLen + num_paritybytes >= BigBuf_max_traceLen() - traceLen) {
|
||||||
tracing = false; // don't trace any more
|
tracing = false; // don't trace any more
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Traceformat:
|
|
||||||
// 32 bits timestamp (little endian)
|
|
||||||
// 16 bits duration (little endian)
|
|
||||||
// 16 bits data length (little endian, Highest Bit used as readerToTag flag)
|
|
||||||
// y Bytes data
|
|
||||||
// x Bytes parity (one byte per 8 bytes data)
|
|
||||||
|
|
||||||
// timestamp (start)
|
uint32_t duration;
|
||||||
trace[traceLen++] = ((timestamp_start >> 0) & 0xff);
|
if (timestamp_end > timestamp_start) {
|
||||||
trace[traceLen++] = ((timestamp_start >> 8) & 0xff);
|
duration = timestamp_end - timestamp_start;
|
||||||
trace[traceLen++] = ((timestamp_start >> 16) & 0xff);
|
} else {
|
||||||
trace[traceLen++] = ((timestamp_start >> 24) & 0xff);
|
duration = (UINT32_MAX - timestamp_start) + timestamp_end;
|
||||||
|
|
||||||
// duration
|
|
||||||
trace[traceLen++] = ((duration >> 0) & 0xff);
|
|
||||||
trace[traceLen++] = ((duration >> 8) & 0xff);
|
|
||||||
|
|
||||||
// data length
|
|
||||||
trace[traceLen++] = ((iLen >> 0) & 0xff);
|
|
||||||
trace[traceLen++] = ((iLen >> 8) & 0xff);
|
|
||||||
|
|
||||||
// readerToTag flag
|
|
||||||
if (!readerToTag) {
|
|
||||||
trace[traceLen - 1] |= 0x80;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (duration > 0x7FFF) {
|
||||||
|
if (DBGLEVEL >= DBG_DEBUG) {
|
||||||
|
Dbprintf("Error in LogTrace: duration too long for 15 bits encoding: 0x%08x start:0x%08x end:0x%08x", duration, timestamp_start, timestamp_end);
|
||||||
|
Dbprintf("Forcing duration = 0");
|
||||||
|
}
|
||||||
|
duration = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
hdr->timestamp = timestamp_start;
|
||||||
|
hdr->duration = duration;
|
||||||
|
hdr->data_len = iLen;
|
||||||
|
hdr->isResponse = !readerToTag;
|
||||||
|
traceLen += TRACELOG_HDR_LEN;
|
||||||
|
|
||||||
// data bytes
|
// data bytes
|
||||||
if (btBytes != NULL && iLen != 0) {
|
if (btBytes != NULL && iLen != 0) {
|
||||||
memcpy(trace + traceLen, btBytes, iLen);
|
memcpy(trace + traceLen, btBytes, iLen);
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
#define BIGBUF_SIZE 40000
|
|
||||||
#define MAX_FRAME_SIZE 256 // maximum allowed ISO14443 frame
|
#define MAX_FRAME_SIZE 256 // maximum allowed ISO14443 frame
|
||||||
#define MAX_PARITY_SIZE ((MAX_FRAME_SIZE + 7) / 8)
|
#define MAX_PARITY_SIZE ((MAX_FRAME_SIZE + 7) / 8)
|
||||||
#define MAX_MIFARE_FRAME_SIZE 18 // biggest Mifare frame is answer to a read (one block = 16 Bytes) + 2 Bytes CRC
|
#define MAX_MIFARE_FRAME_SIZE 18 // biggest Mifare frame is answer to a read (one block = 16 Bytes) + 2 Bytes CRC
|
||||||
|
@ -23,8 +22,10 @@
|
||||||
#define DMA_BUFFER_SIZE 256 //128 (how big is the dma?!?
|
#define DMA_BUFFER_SIZE 256 //128 (how big is the dma?!?
|
||||||
|
|
||||||
uint8_t *BigBuf_get_addr(void);
|
uint8_t *BigBuf_get_addr(void);
|
||||||
|
uint32_t BigBuf_get_size(void);
|
||||||
uint8_t *BigBuf_get_EM_addr(void);
|
uint8_t *BigBuf_get_EM_addr(void);
|
||||||
uint16_t BigBuf_max_traceLen(void);
|
uint16_t BigBuf_max_traceLen(void);
|
||||||
|
void BigBuf_initialize(void);
|
||||||
void BigBuf_Clear(void);
|
void BigBuf_Clear(void);
|
||||||
void BigBuf_Clear_ext(bool verbose);
|
void BigBuf_Clear_ext(bool verbose);
|
||||||
void BigBuf_Clear_keep_EM(void);
|
void BigBuf_Clear_keep_EM(void);
|
||||||
|
|
|
@ -20,8 +20,7 @@ endif
|
||||||
#in the next section to remove that particular feature from compilation.
|
#in the next section to remove that particular feature from compilation.
|
||||||
# NO space,TABs after the "\" sign.
|
# NO space,TABs after the "\" sign.
|
||||||
APP_CFLAGS = $(PLATFORM_DEFS) \
|
APP_CFLAGS = $(PLATFORM_DEFS) \
|
||||||
-DON_DEVICE \
|
-ffunction-sections -fdata-sections
|
||||||
-fno-strict-aliasing -ffunction-sections -fdata-sections
|
|
||||||
|
|
||||||
SRC_LF = lfops.c lfsampling.c pcf7931.c lfdemod.c lfadc.c
|
SRC_LF = lfops.c lfsampling.c pcf7931.c lfdemod.c lfadc.c
|
||||||
SRC_ISO15693 = iso15693.c iso15693tools.c
|
SRC_ISO15693 = iso15693.c iso15693tools.c
|
||||||
|
@ -64,6 +63,12 @@ else
|
||||||
SRC_HITAG =
|
SRC_HITAG =
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifneq (,$(findstring WITH_EM4x50,$(APP_CFLAGS)))
|
||||||
|
SRC_EM4x50 = em4x50.c
|
||||||
|
else
|
||||||
|
SRC_EM4x50 =
|
||||||
|
endif
|
||||||
|
|
||||||
ifneq (,$(findstring WITH_LCD,$(APP_CFLAGS)))
|
ifneq (,$(findstring WITH_LCD,$(APP_CFLAGS)))
|
||||||
SRC_LCD = fonts.c LCD.c
|
SRC_LCD = fonts.c LCD.c
|
||||||
else
|
else
|
||||||
|
@ -76,13 +81,13 @@ include Standalone/Makefile.inc
|
||||||
#the FPGA bitstream files. Note: order matters!
|
#the FPGA bitstream files. Note: order matters!
|
||||||
FPGA_BITSTREAMS = fpga_lf.bit fpga_hf.bit
|
FPGA_BITSTREAMS = fpga_lf.bit fpga_hf.bit
|
||||||
|
|
||||||
#the zlib source files required for decompressing the fpga config at run time
|
#the lz4 source files required for decompressing the fpga config at run time
|
||||||
SRC_ZLIB = inflate.c inffast.c inftrees.c adler32.c zutil.c
|
SRC_LZ4 = lz4.c
|
||||||
#additional defines required to compile zlib
|
#additional defines required to compile lz4
|
||||||
ZLIB_CFLAGS = -DZ_SOLO -DZ_PREFIX -DNO_GZIP -DZLIB_PM3_TUNED
|
LZ4_CFLAGS = -DLZ4_MEMORY_USAGE=8
|
||||||
APP_CFLAGS += $(ZLIB_CFLAGS)
|
APP_CFLAGS += $(LZ4_CFLAGS)
|
||||||
# zlib includes:
|
# lz4 includes:
|
||||||
APP_CFLAGS += -I../common/zlib
|
APP_CFLAGS += -I../common/lz4
|
||||||
|
|
||||||
# stdint.h provided locally until GCC 4.5 becomes C99 compliant,
|
# stdint.h provided locally until GCC 4.5 becomes C99 compliant,
|
||||||
# stack-protect , no-pie reduces size on Gentoo Hardened 8.2 gcc
|
# stack-protect , no-pie reduces size on Gentoo Hardened 8.2 gcc
|
||||||
|
@ -94,13 +99,22 @@ THUMBSRC = start.c \
|
||||||
$(SRC_ISO15693) \
|
$(SRC_ISO15693) \
|
||||||
$(SRC_NFCBARCODE) \
|
$(SRC_NFCBARCODE) \
|
||||||
$(SRC_LF) \
|
$(SRC_LF) \
|
||||||
$(SRC_ZLIB) \
|
$(SRC_LZ4) \
|
||||||
$(SRC_LEGIC) \
|
$(SRC_LEGIC) \
|
||||||
$(SRC_FLASH) \
|
$(SRC_FLASH) \
|
||||||
$(SRC_SMARTCARD) \
|
$(SRC_SMARTCARD) \
|
||||||
$(SRC_FPC) \
|
$(SRC_FPC) \
|
||||||
$(SRC_HITAG) \
|
$(SRC_HITAG) \
|
||||||
|
$(SRC_EM4x50) \
|
||||||
$(SRC_SPIFFS) \
|
$(SRC_SPIFFS) \
|
||||||
|
$(SRC_ISO14443a) \
|
||||||
|
$(SRC_ISO14443b) \
|
||||||
|
$(SRC_CRAPTO1) \
|
||||||
|
$(SRC_ICLASS) \
|
||||||
|
$(SRC_EMV) \
|
||||||
|
$(SRC_CRC) \
|
||||||
|
$(SRC_FELICA) \
|
||||||
|
$(SRC_STANDALONE) \
|
||||||
appmain.c \
|
appmain.c \
|
||||||
printf.c \
|
printf.c \
|
||||||
dbprint.c \
|
dbprint.c \
|
||||||
|
@ -115,14 +129,6 @@ THUMBSRC = start.c \
|
||||||
|
|
||||||
# These are to be compiled in ARM mode
|
# These are to be compiled in ARM mode
|
||||||
ARMSRC = fpgaloader.c \
|
ARMSRC = fpgaloader.c \
|
||||||
$(SRC_ISO14443a) \
|
|
||||||
$(SRC_ISO14443b) \
|
|
||||||
$(SRC_CRAPTO1) \
|
|
||||||
$(SRC_ICLASS) \
|
|
||||||
$(SRC_EMV) \
|
|
||||||
$(SRC_CRC) \
|
|
||||||
$(SRC_FELICA) \
|
|
||||||
$(SRC_STANDALONE) \
|
|
||||||
parity.c \
|
parity.c \
|
||||||
usb_cdc.c \
|
usb_cdc.c \
|
||||||
cmd.c
|
cmd.c
|
||||||
|
@ -133,8 +139,6 @@ VERSIONSRC = version.c \
|
||||||
# Do not move this inclusion before the definition of {THUMB,ASM,ARM}SRC
|
# Do not move this inclusion before the definition of {THUMB,ASM,ARM}SRC
|
||||||
include ../common_arm/Makefile.common
|
include ../common_arm/Makefile.common
|
||||||
|
|
||||||
COMMON_FLAGS = -Os
|
|
||||||
|
|
||||||
INSTALLFW = $(OBJDIR)/fullimage.elf
|
INSTALLFW = $(OBJDIR)/fullimage.elf
|
||||||
ifneq (,$(FWTAG))
|
ifneq (,$(FWTAG))
|
||||||
INSTALLFWTAG = $(notdir $(INSTALLFW:%.elf=%-$(FWTAG).elf))
|
INSTALLFWTAG = $(notdir $(INSTALLFW:%.elf=%-$(FWTAG).elf))
|
||||||
|
@ -155,9 +159,9 @@ showinfo:
|
||||||
# version.c should be remade on every time fullimage.stage1.elf should be remade
|
# version.c should be remade on every time fullimage.stage1.elf should be remade
|
||||||
version.c: default_version.c $(OBJDIR)/fpga_version_info.o $(OBJDIR)/fpga_all.o $(THUMBOBJ) $(ARMOBJ)
|
version.c: default_version.c $(OBJDIR)/fpga_version_info.o $(OBJDIR)/fpga_all.o $(THUMBOBJ) $(ARMOBJ)
|
||||||
$(info [-] GEN $@)
|
$(info [-] GEN $@)
|
||||||
$(Q)sh ../tools/mkversion.sh > $@ || perl ../tools/mkversion.pl > $@ || $(CP) $^ $@
|
$(Q)$(SH) ../tools/mkversion.sh > $@ || $(PERL) ../tools/mkversion.pl > $@ || $(CP) $< $@
|
||||||
|
|
||||||
fpga_version_info.c: $(FPGA_BITSTREAMS) | $(FPGA_COMPRESSOR)
|
fpga_version_info.c: $(FPGA_BITSTREAMS) $(FPGA_COMPRESSOR)
|
||||||
$(info [-] GEN $@)
|
$(info [-] GEN $@)
|
||||||
$(Q)$(FPGA_COMPRESSOR) -v $(filter %.bit,$^) $@
|
$(Q)$(FPGA_COMPRESSOR) -v $(filter %.bit,$^) $@
|
||||||
|
|
||||||
|
@ -179,7 +183,7 @@ $(FPGA_COMPRESSOR):
|
||||||
|
|
||||||
$(OBJDIR)/fullimage.stage1.elf: $(VERSIONOBJ) $(OBJDIR)/fpga_all.o $(THUMBOBJ) $(ARMOBJ)
|
$(OBJDIR)/fullimage.stage1.elf: $(VERSIONOBJ) $(OBJDIR)/fpga_all.o $(THUMBOBJ) $(ARMOBJ)
|
||||||
$(info [=] LD $@)
|
$(info [=] LD $@)
|
||||||
$(Q)$(CC) $(LDFLAGS) -Wl,-T,ldscript,-Map,$(patsubst %.elf,%.map,$@) -o $@ $^ $(LIBS)
|
$(Q)$(CC) $(CROSS_LDFLAGS) -Wl,-T,ldscript,-Map,$(patsubst %.elf,%.map,$@) -o $@ $^ $(LIBS)
|
||||||
|
|
||||||
$(OBJDIR)/fullimage.nodata.bin: $(OBJDIR)/fullimage.stage1.elf
|
$(OBJDIR)/fullimage.nodata.bin: $(OBJDIR)/fullimage.stage1.elf
|
||||||
$(info [-] GEN $@)
|
$(info [-] GEN $@)
|
||||||
|
@ -207,7 +211,7 @@ $(OBJDIR)/fullimage.data.o: $(OBJDIR)/fullimage.data.bin.z
|
||||||
|
|
||||||
$(OBJDIR)/fullimage.elf: $(OBJDIR)/fullimage.nodata.o $(OBJDIR)/fullimage.data.o
|
$(OBJDIR)/fullimage.elf: $(OBJDIR)/fullimage.nodata.o $(OBJDIR)/fullimage.data.o
|
||||||
$(info [=] LD $@)
|
$(info [=] LD $@)
|
||||||
$(Q)$(CC) $(LDFLAGS) -Wl,-T,ldscript,-e,_osimage_entry,-Map,$(patsubst %.elf,%.map,$@) -o $@ $^
|
$(Q)$(CC) $(CROSS_LDFLAGS) -Wl,-T,ldscript,-e,_osimage_entry,-Map,$(patsubst %.elf,%.map,$@) -o $@ $^
|
||||||
|
|
||||||
tarbin: $(OBJS)
|
tarbin: $(OBJS)
|
||||||
$(info TAR $@)
|
$(info TAR $@)
|
||||||
|
|
|
@ -81,12 +81,12 @@
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
uint8_t cjuid[10];
|
static uint8_t cjuid[10];
|
||||||
uint32_t cjcuid;
|
static uint32_t cjcuid;
|
||||||
iso14a_card_select_t p_card;
|
static iso14a_card_select_t p_card;
|
||||||
int currline;
|
static int currline;
|
||||||
int currfline;
|
static int currfline;
|
||||||
int curlline;
|
static int curlline;
|
||||||
|
|
||||||
// TODO : Implement fast read of KEYS like in RFIdea
|
// TODO : Implement fast read of KEYS like in RFIdea
|
||||||
// also http://ext.delaat.net/rp/2015-2016/p04/report.pdf
|
// also http://ext.delaat.net/rp/2015-2016/p04/report.pdf
|
||||||
|
@ -104,12 +104,7 @@ static const uint8_t is_hex[] = {
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
};
|
};
|
||||||
|
|
||||||
// Note: inlining this function would fail with -Os
|
|
||||||
#ifdef __OPTIMIZE_SIZE__
|
|
||||||
static uint64_t hex2i(const char *s) {
|
static uint64_t hex2i(const char *s) {
|
||||||
#else
|
|
||||||
static inline uint64_t hex2i(const char *s) {
|
|
||||||
#endif
|
|
||||||
uint64_t val = 0;
|
uint64_t val = 0;
|
||||||
if (s == NULL || s[0] == 0)
|
if (s == NULL || s[0] == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -167,7 +162,7 @@ static void scan_keys(const char *str, int len, uint64_t *user_data) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MFC1KSchema Schemas[MAX_SCHEMAS];
|
static MFC1KSchema Schemas[MAX_SCHEMAS];
|
||||||
|
|
||||||
/*MFC1KSchema Noralsy = {
|
/*MFC1KSchema Noralsy = {
|
||||||
.name = "Noralsy",
|
.name = "Noralsy",
|
||||||
|
@ -201,7 +196,7 @@ MFC1KSchema InfiHexact = {.name = "Infineon/Hexact",
|
||||||
0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76}};
|
0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76}};
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int total_schemas = 0;
|
static int total_schemas = 0;
|
||||||
|
|
||||||
static void add_schema(MFC1KSchema *p, MFC1KSchema a, int *schemas_counter) {
|
static void add_schema(MFC1KSchema *p, MFC1KSchema a, int *schemas_counter) {
|
||||||
if (*schemas_counter < MAX_SCHEMAS) {
|
if (*schemas_counter < MAX_SCHEMAS) {
|
||||||
|
@ -237,14 +232,6 @@ static void cjSetCursLeft(void) {
|
||||||
|
|
||||||
static void cjTabulize(void) { DbprintfEx(FLAG_RAWPRINT, "\t\t\t"); }
|
static void cjTabulize(void) { DbprintfEx(FLAG_RAWPRINT, "\t\t\t"); }
|
||||||
|
|
||||||
/*
|
|
||||||
void cjPrintKey(uint64_t key, uint8_t *foundKey, uint16_t sectorNo, uint8_t type) {
|
|
||||||
char tosendkey[13];
|
|
||||||
sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[0], foundKey[1], foundKey[2], foundKey[3], foundKey[4],
|
|
||||||
foundKey[5]); cjSetCursRight(); DbprintfEx(FLAG_NEWLINE, "SEC: %02x | KEY : %s | TYP: %d", sectorNo, tosendkey, type);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
static char *ReadSchemasFromSPIFFS(char *filename) {
|
static char *ReadSchemasFromSPIFFS(char *filename) {
|
||||||
SpinOff(0);
|
SpinOff(0);
|
||||||
|
|
||||||
|
@ -297,6 +284,7 @@ static void ReadLastTagFromFlash(void) {
|
||||||
// this one will handle filetype (symlink or not) and resolving by itself
|
// this one will handle filetype (symlink or not) and resolving by itself
|
||||||
rdv40_spiffs_read_as_filetype((char *)HFCOLIN_LASTTAG_SYMLINK, (uint8_t *)mem, len, RDV40_SPIFFS_SAFETY_SAFE);
|
rdv40_spiffs_read_as_filetype((char *)HFCOLIN_LASTTAG_SYMLINK, (uint8_t *)mem, len, RDV40_SPIFFS_SAFETY_SAFE);
|
||||||
|
|
||||||
|
// copy 64blocks (16bytes) starting w block0, to emulator mem.
|
||||||
emlSetMem(mem, 0, 64);
|
emlSetMem(mem, 0, 64);
|
||||||
|
|
||||||
DbprintfEx(FLAG_NEWLINE, "[OK] Last tag recovered from FLASHMEM set to emulator");
|
DbprintfEx(FLAG_NEWLINE, "[OK] Last tag recovered from FLASHMEM set to emulator");
|
||||||
|
@ -335,16 +323,22 @@ void WriteTagToFlash(uint32_t uid, size_t size) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModInfo(void) { DbpString(" HF Mifare ultra fast sniff/sim/clone - aka VIGIKPWN (Colin Brigato)"); }
|
void ModInfo(void) {
|
||||||
|
DbpString(" HF Mifare ultra fast sniff/sim/clone - aka VIGIKPWN (Colin Brigato)");
|
||||||
|
}
|
||||||
|
|
||||||
void RunMod(void) {
|
void RunMod(void) {
|
||||||
StandAloneMode();
|
StandAloneMode();
|
||||||
|
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
||||||
|
Dbprintf(">> HF Mifare ultra fast sniff/sim/clone a.k.a VIGIKPWN Started <<");
|
||||||
|
|
||||||
|
// turn off all debugging.
|
||||||
|
DBGLEVEL = DBG_NONE;
|
||||||
|
|
||||||
// add_schema(Schemas, Noralsy, &total_schemas);
|
// add_schema(Schemas, Noralsy, &total_schemas);
|
||||||
// add_schema(Schemas, InfiHexact, &total_schemas);
|
// add_schema(Schemas, InfiHexact, &total_schemas);
|
||||||
// add_schema_from_json_in_spiffs((char *)HFCOLIN_URMETCAPTIVE_JSON);
|
// add_schema_from_json_in_spiffs((char *)HFCOLIN_URMETCAPTIVE_JSON);
|
||||||
// add_schema(Schemas, UrmetCaptive, &total_schemas);
|
// add_schema(Schemas, UrmetCaptive, &total_schemas);
|
||||||
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
|
||||||
|
|
||||||
currline = 20;
|
currline = 20;
|
||||||
curlline = 20;
|
curlline = 20;
|
||||||
|
@ -391,11 +385,11 @@ void RunMod(void) {
|
||||||
ACCBITS : 796788[00]+VALUE
|
ACCBITS : 796788[00]+VALUE
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//----------------------------
|
// ----------------------------
|
||||||
// Set of keys to be used.
|
// Set of keys to be used.
|
||||||
// This should cover ~98% of
|
// This should cover ~98% of
|
||||||
// French VIGIK system @2017
|
// French VIGIK system @2017
|
||||||
//----------------------------
|
// ----------------------------
|
||||||
|
|
||||||
const uint64_t mfKeys[] = {
|
const uint64_t mfKeys[] = {
|
||||||
0xffffffffffff, // TRANSPORTS
|
0xffffffffffff, // TRANSPORTS
|
||||||
|
@ -464,7 +458,6 @@ void RunMod(void) {
|
||||||
bool err = 0;
|
bool err = 0;
|
||||||
bool trapped = 0;
|
bool trapped = 0;
|
||||||
bool allKeysFound = true;
|
bool allKeysFound = true;
|
||||||
|
|
||||||
uint32_t size = mfKeysCnt;
|
uint32_t size = mfKeysCnt;
|
||||||
|
|
||||||
// banner:
|
// banner:
|
||||||
|
@ -492,7 +485,7 @@ failtag:
|
||||||
SpinOff(50);
|
SpinOff(50);
|
||||||
LED_A_ON();
|
LED_A_ON();
|
||||||
uint8_t ticker = 0;
|
uint8_t ticker = 0;
|
||||||
// while (!BUTTON_PRESS() && !iso14443a_select_card(cjuid, NULL, &cjcuid, true, 0, true))
|
|
||||||
while (!iso14443a_select_card(cjuid, &p_card, &cjcuid, true, 0, true)) {
|
while (!iso14443a_select_card(cjuid, &p_card, &cjcuid, true, 0, true)) {
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
|
|
||||||
|
@ -510,8 +503,8 @@ failtag:
|
||||||
}
|
}
|
||||||
|
|
||||||
SpinOff(50);
|
SpinOff(50);
|
||||||
|
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
|
|
||||||
vtsend_cursor_position_restore(NULL);
|
vtsend_cursor_position_restore(NULL);
|
||||||
DbprintfEx(FLAG_NEWLINE, "\t\t\t%s[ GOT a Tag ! ]%s", _XGREEN_, _XWHITE_);
|
DbprintfEx(FLAG_NEWLINE, "\t\t\t%s[ GOT a Tag ! ]%s", _XGREEN_, _XWHITE_);
|
||||||
cjSetCursLeft();
|
cjSetCursLeft();
|
||||||
|
@ -539,7 +532,7 @@ failtag:
|
||||||
uint32_t start_time = GetTickCount();
|
uint32_t start_time = GetTickCount();
|
||||||
uint32_t delta_time = 0;
|
uint32_t delta_time = 0;
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// WE SHOULD FIND A WAY TO GET UID TO AVOID THIS "TESTRUN"
|
// WE SHOULD FIND A WAY TO GET UID TO AVOID THIS "TESTRUN"
|
||||||
// --------------------------------------------------------
|
// --------------------------------------------------------
|
||||||
// + HERE IS TO BE THOUGHT AS ONLY A KEY SHOULD BE CHECK
|
// + HERE IS TO BE THOUGHT AS ONLY A KEY SHOULD BE CHECK
|
||||||
|
@ -549,7 +542,7 @@ failtag:
|
||||||
// `-+ THEN FILL EMULATOR WITH B KEEY
|
// `-+ THEN FILL EMULATOR WITH B KEEY
|
||||||
// `-+ THEN EMULATOR WITH CARD WITH B KEY
|
// `-+ THEN EMULATOR WITH CARD WITH B KEY
|
||||||
// `-+ IF IT HAS FAILED OF ANY OF SORT THEN WE ARE MARRON LIKE POMALO.
|
// `-+ IF IT HAS FAILED OF ANY OF SORT THEN WE ARE MARRON LIKE POMALO.
|
||||||
//----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// AN EVEN BETTER IMPLEMENTATION IS TO CHECK EVERY KEY FOR SECTOR 0 KEY A
|
// AN EVEN BETTER IMPLEMENTATION IS TO CHECK EVERY KEY FOR SECTOR 0 KEY A
|
||||||
// THEN IF FOUND CHECK THE SAME KEY FOR NEXT SECTOR ONLY KEY A
|
// THEN IF FOUND CHECK THE SAME KEY FOR NEXT SECTOR ONLY KEY A
|
||||||
// THEN IF FAIL CHECK EVERY SECTOR A KEY FOR EVERY OTHER KEY BUT NOT THE BLOCK
|
// THEN IF FAIL CHECK EVERY SECTOR A KEY FOR EVERY OTHER KEY BUT NOT THE BLOCK
|
||||||
|
@ -563,7 +556,7 @@ failtag:
|
||||||
// DERIVATION
|
// DERIVATION
|
||||||
// THEN IF B KEY IS NOT OF THIS SCHEME CHECK EVERY REMAINING B KEYED SECTOR
|
// THEN IF B KEY IS NOT OF THIS SCHEME CHECK EVERY REMAINING B KEYED SECTOR
|
||||||
// WITH EVERY REMAINING KEYS, BUT DISCARDING ANY DEFAULT TRANSPORT KEYS.
|
// WITH EVERY REMAINING KEYS, BUT DISCARDING ANY DEFAULT TRANSPORT KEYS.
|
||||||
//-----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// also we could avoid first UID check for every block
|
// also we could avoid first UID check for every block
|
||||||
|
|
||||||
// then let's expose this optimal case of well known vigik schemes :
|
// then let's expose this optimal case of well known vigik schemes :
|
||||||
|
@ -630,7 +623,6 @@ failtag:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* etc etc for testing schemes quick schemes */
|
/* etc etc for testing schemes quick schemes */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -646,7 +638,7 @@ failtag:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Settings keys to emulator */
|
// Settings keys to emulator
|
||||||
emlClearMem();
|
emlClearMem();
|
||||||
uint8_t mblock[16];
|
uint8_t mblock[16];
|
||||||
for (uint8_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) {
|
for (uint8_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) {
|
||||||
|
@ -660,7 +652,7 @@ failtag:
|
||||||
|
|
||||||
DbprintfEx(FLAG_NEWLINE, "%s>>%s Setting Keys->Emulator MEM...[%sOK%s]", _XYELLOW_, _XWHITE_, _XGREEN_, _XWHITE_);
|
DbprintfEx(FLAG_NEWLINE, "%s>>%s Setting Keys->Emulator MEM...[%sOK%s]", _XYELLOW_, _XWHITE_, _XGREEN_, _XWHITE_);
|
||||||
|
|
||||||
/* filling TAG to emulator */
|
// filling TAG to emulator
|
||||||
int filled;
|
int filled;
|
||||||
cjSetCursLeft();
|
cjSetCursLeft();
|
||||||
|
|
||||||
|
@ -671,11 +663,10 @@ failtag:
|
||||||
|
|
||||||
DbprintfEx(FLAG_NEWLINE, "%s>>%s W_FAILURE ! %sTrying fallback B keys....", _XRED_, _XORANGE_, _XWHITE_);
|
DbprintfEx(FLAG_NEWLINE, "%s>>%s W_FAILURE ! %sTrying fallback B keys....", _XRED_, _XORANGE_, _XWHITE_);
|
||||||
|
|
||||||
/* no trace, no dbg */
|
// no trace, no dbg
|
||||||
filled = e_MifareECardLoad(sectorsCnt, 1);
|
filled = e_MifareECardLoad(sectorsCnt, 1);
|
||||||
if (filled != PM3_SUCCESS) {
|
if (filled != PM3_SUCCESS) {
|
||||||
cjSetCursLeft();
|
cjSetCursLeft();
|
||||||
|
|
||||||
DbprintfEx(FLAG_NEWLINE, "FATAL:EML_FALLBACKFILL_B");
|
DbprintfEx(FLAG_NEWLINE, "FATAL:EML_FALLBACKFILL_B");
|
||||||
SpinErr(LED_C, 100, 8);
|
SpinErr(LED_C, 100, 8);
|
||||||
SpinOff(100);
|
SpinOff(100);
|
||||||
|
@ -722,10 +713,9 @@ readysim:
|
||||||
SpinOff(100);
|
SpinOff(100);
|
||||||
LED_C_ON();
|
LED_C_ON();
|
||||||
|
|
||||||
DBGLEVEL = DBG_NONE;
|
/*
|
||||||
|
uint16_t flags = 0;
|
||||||
//uint16_t flags=0;
|
switch (p_card.uidlen) {
|
||||||
/*switch (p_card.uidlen) {
|
|
||||||
case 10:
|
case 10:
|
||||||
flags = FLAG_10B_UID_IN_DATA;
|
flags = FLAG_10B_UID_IN_DATA;
|
||||||
break;
|
break;
|
||||||
|
@ -738,19 +728,18 @@ readysim:
|
||||||
default:
|
default:
|
||||||
flags = FLAG_UID_IN_EMUL;
|
flags = FLAG_UID_IN_EMUL;
|
||||||
break;
|
break;
|
||||||
}*/
|
}
|
||||||
|
|
||||||
// Use UID, SAK, ATQA from EMUL, if uid not defined
|
// Use UID, SAK, ATQA from EMUL, if uid not defined
|
||||||
// if ((flags & (FLAG_4B_UID_IN_DATA | FLAG_7B_UID_IN_DATA | FLAG_10B_UID_IN_DATA)) == 0) {
|
if ((flags & (FLAG_4B_UID_IN_DATA | FLAG_7B_UID_IN_DATA | FLAG_10B_UID_IN_DATA)) == 0) {
|
||||||
//flags |= FLAG_UID_IN_EMUL;
|
flags |= FLAG_UID_IN_EMUL;
|
||||||
//}
|
}
|
||||||
//flags |= FLAG_MF_1K;
|
flags |= FLAG_MF_1K;
|
||||||
//if ((flags & (FLAG_4B_UID_IN_DATA | FLAG_7B_UID_IN_DATA | FLAG_10B_UID_IN_DATA)) == 0) {
|
if ((flags & (FLAG_4B_UID_IN_DATA | FLAG_7B_UID_IN_DATA | FLAG_10B_UID_IN_DATA)) == 0) {
|
||||||
// flags |= FLAG_UID_IN_EMUL;
|
flags |= FLAG_UID_IN_EMUL;
|
||||||
//}
|
}
|
||||||
//flags = 0x10;
|
flags = 0x10;
|
||||||
uint16_t flags = 0;
|
*/
|
||||||
flags = 16;
|
uint16_t flags = FLAG_UID_IN_EMUL;
|
||||||
DbprintfEx(FLAG_NEWLINE, "\n\n\n\n\n\n\n\nn\n\nn\n\n\nflags: %d (0x%02x)", flags, flags);
|
DbprintfEx(FLAG_NEWLINE, "\n\n\n\n\n\n\n\nn\n\nn\n\n\nflags: %d (0x%02x)", flags, flags);
|
||||||
cjSetCursLeft();
|
cjSetCursLeft();
|
||||||
SpinOff(1000);
|
SpinOff(1000);
|
||||||
|
@ -794,8 +783,6 @@ readysim:
|
||||||
* - tracing is falsed
|
* - tracing is falsed
|
||||||
*/
|
*/
|
||||||
int e_MifareECardLoad(uint32_t numofsectors, uint8_t keytype) {
|
int e_MifareECardLoad(uint32_t numofsectors, uint8_t keytype) {
|
||||||
DBGLEVEL = DBG_NONE;
|
|
||||||
|
|
||||||
uint8_t numSectors = numofsectors;
|
uint8_t numSectors = numofsectors;
|
||||||
uint8_t keyType = keytype;
|
uint8_t keyType = keytype;
|
||||||
|
|
||||||
|
@ -807,7 +794,6 @@ int e_MifareECardLoad(uint32_t numofsectors, uint8_t keytype) {
|
||||||
uint8_t dataoutbuf2[16];
|
uint8_t dataoutbuf2[16];
|
||||||
|
|
||||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||||
|
|
||||||
clear_trace();
|
clear_trace();
|
||||||
set_tracing(false);
|
set_tracing(false);
|
||||||
|
|
||||||
|
@ -815,24 +801,17 @@ int e_MifareECardLoad(uint32_t numofsectors, uint8_t keytype) {
|
||||||
|
|
||||||
if (!iso14443a_select_card(cjuid, &p_card, &cjcuid, true, 0, true)) {
|
if (!iso14443a_select_card(cjuid, &p_card, &cjcuid, true, 0, true)) {
|
||||||
isOK = false;
|
isOK = false;
|
||||||
if (DBGLEVEL >= 1)
|
|
||||||
DbprintfEx(FLAG_RAWPRINT, "Can't select card");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint8_t s = 0; isOK && s < numSectors; s++) {
|
for (uint8_t s = 0; isOK && s < numSectors; s++) {
|
||||||
uint64_t ui64Key = emlGetKey(s, keyType);
|
uint64_t ui64Key = emlGetKey(s, keyType);
|
||||||
if (s == 0) {
|
if (s == 0) {
|
||||||
if (isOK && mifare_classic_auth(pcs, cjcuid, FirstBlockOfSector(s), keyType, ui64Key, AUTH_FIRST)) {
|
if (isOK && mifare_classic_auth(pcs, cjcuid, FirstBlockOfSector(s), keyType, ui64Key, AUTH_FIRST)) {
|
||||||
|
|
||||||
if (DBGLEVEL >= 1)
|
|
||||||
DbprintfEx(FLAG_NEWLINE, "Sector[%2d]. Auth error", s);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (isOK && mifare_classic_auth(pcs, cjcuid, FirstBlockOfSector(s), keyType, ui64Key, AUTH_NESTED)) {
|
if (isOK && mifare_classic_auth(pcs, cjcuid, FirstBlockOfSector(s), keyType, ui64Key, AUTH_NESTED)) {
|
||||||
isOK = false;
|
isOK = false;
|
||||||
if (DBGLEVEL >= 1)
|
|
||||||
DbprintfEx(FLAG_NEWLINE, "Sector[%2d]. Auth nested error", s);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -840,8 +819,6 @@ int e_MifareECardLoad(uint32_t numofsectors, uint8_t keytype) {
|
||||||
for (uint8_t blockNo = 0; isOK && blockNo < NumBlocksPerSector(s); blockNo++) {
|
for (uint8_t blockNo = 0; isOK && blockNo < NumBlocksPerSector(s); blockNo++) {
|
||||||
if (isOK && mifare_classic_readblock(pcs, cjcuid, FirstBlockOfSector(s) + blockNo, dataoutbuf)) {
|
if (isOK && mifare_classic_readblock(pcs, cjcuid, FirstBlockOfSector(s) + blockNo, dataoutbuf)) {
|
||||||
isOK = false;
|
isOK = false;
|
||||||
if (DBGLEVEL >= 1)
|
|
||||||
DbprintfEx(FLAG_NEWLINE, "Error reading sector %2d block %2d", s, blockNo);
|
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
if (isOK) {
|
if (isOK) {
|
||||||
|
@ -857,23 +834,18 @@ int e_MifareECardLoad(uint32_t numofsectors, uint8_t keytype) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mifare_classic_halt(pcs, cjcuid)) {
|
int res = mifare_classic_halt(pcs, cjcuid);
|
||||||
if (DBGLEVEL >= 1)
|
(void)res;
|
||||||
DbprintfEx(FLAG_NEWLINE, "Halt error");
|
|
||||||
};
|
|
||||||
|
|
||||||
crypto1_deinit(pcs);
|
crypto1_deinit(pcs);
|
||||||
|
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
|
|
||||||
return (isOK) ? PM3_SUCCESS : PM3_EUNDEF;
|
return (isOK) ? PM3_SUCCESS : PM3_EUNDEF;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* the chk function is a piwi'ed(tm) check that will try all keys for
|
/* the chk function is a piwi'ed(tm) check that will try all keys for
|
||||||
a particular sector. also no tracing no dbg */
|
a particular sector. also no tracing no dbg */
|
||||||
int cjat91_saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, uint8_t keyCount, uint8_t *datain,
|
int cjat91_saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace,
|
||||||
uint64_t *key) {
|
uint8_t keyCount, uint8_t *datain, uint64_t *key) {
|
||||||
DBGLEVEL = DBG_NONE;
|
|
||||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||||
set_tracing(false);
|
set_tracing(false);
|
||||||
|
|
||||||
|
@ -881,14 +853,16 @@ int cjat91_saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, ui
|
||||||
struct Crypto1State *pcs;
|
struct Crypto1State *pcs;
|
||||||
pcs = &mpcs;
|
pcs = &mpcs;
|
||||||
|
|
||||||
for (int i = 0; i < keyCount; ++i) {
|
int retval = -1;
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < keyCount; i++) {
|
||||||
|
|
||||||
/* no need for anticollision. just verify tag is still here */
|
/* no need for anticollision. just verify tag is still here */
|
||||||
// if (!iso14443a_fast_select_card(cjuid, 0)) {
|
// if (!iso14443a_fast_select_card(cjuid, 0)) {
|
||||||
if (!iso14443a_select_card(cjuid, &p_card, &cjcuid, true, 0, true)) {
|
if (!iso14443a_select_card(cjuid, &p_card, &cjcuid, true, 0, true)) {
|
||||||
cjSetCursLeft();
|
cjSetCursLeft();
|
||||||
DbprintfEx(FLAG_NEWLINE, "%sFATAL%s : E_MF_LOSTTAG", _XRED_, _XWHITE_);
|
DbprintfEx(FLAG_NEWLINE, "%sFATAL%s : E_MF_LOSTTAG", _XRED_, _XWHITE_);
|
||||||
return -1;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t ui64Key = bytes_to_num(datain + i * 6, 6);
|
uint64_t ui64Key = bytes_to_num(datain + i * 6, 6);
|
||||||
|
@ -899,15 +873,13 @@ int cjat91_saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, ui
|
||||||
SpinDelayUs(AUTHENTICATION_TIMEOUT);
|
SpinDelayUs(AUTHENTICATION_TIMEOUT);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
crypto1_deinit(pcs);
|
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
|
||||||
*key = ui64Key;
|
*key = ui64Key;
|
||||||
return i;
|
retval = i;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
crypto1_deinit(pcs);
|
crypto1_deinit(pcs);
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
|
return retval;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void saMifareMakeTag(void) {
|
void saMifareMakeTag(void) {
|
||||||
|
@ -925,7 +897,6 @@ void saMifareMakeTag(void) {
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
for (int blockNum = 0; blockNum < 16 * 4; blockNum++) {
|
for (int blockNum = 0; blockNum < 16 * 4; blockNum++) {
|
||||||
uint8_t mblock[16];
|
uint8_t mblock[16];
|
||||||
// cnt = 0;
|
|
||||||
emlGetMem(mblock, blockNum, 1);
|
emlGetMem(mblock, blockNum, 1);
|
||||||
// switch on field and send magic sequence
|
// switch on field and send magic sequence
|
||||||
if (blockNum == 0)
|
if (blockNum == 0)
|
||||||
|
@ -940,21 +911,15 @@ void saMifareMakeTag(void) {
|
||||||
flags = 0x04 + 0x10;
|
flags = 0x04 + 0x10;
|
||||||
|
|
||||||
if (saMifareCSetBlock(0, flags & 0xFE, blockNum, mblock)) {
|
if (saMifareCSetBlock(0, flags & 0xFE, blockNum, mblock)) {
|
||||||
//&& cnt <= retry) {
|
|
||||||
// cnt++;
|
|
||||||
cjSetCursFRight();
|
cjSetCursFRight();
|
||||||
if (currfline > 53) {
|
if (currfline > 53) {
|
||||||
currfline = 54;
|
currfline = 54;
|
||||||
}
|
}
|
||||||
DbprintfEx(FLAG_NEWLINE, "Block :%02x %sOK%s", blockNum, _XGREEN_, _XWHITE_);
|
DbprintfEx(FLAG_NEWLINE, "Block :%02x %sOK%s", blockNum, _XGREEN_, _XWHITE_);
|
||||||
// DbprintfEx(FLAG_RAWPRINT,"FATAL:E_MF_CHINESECOOK_NORICE");
|
|
||||||
// cfail=1;
|
|
||||||
// return;
|
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
cjSetCursLeft();
|
cjSetCursLeft();
|
||||||
cjSetCursLeft();
|
cjSetCursLeft();
|
||||||
|
|
||||||
DbprintfEx(FLAG_NEWLINE, "`--> %sFAIL%s : CHN_FAIL_BLK_%02x_NOK", _XRED_, _XWHITE_, blockNum);
|
DbprintfEx(FLAG_NEWLINE, "`--> %sFAIL%s : CHN_FAIL_BLK_%02x_NOK", _XRED_, _XWHITE_, blockNum);
|
||||||
cjSetCursFRight();
|
cjSetCursFRight();
|
||||||
DbprintfEx(FLAG_NEWLINE, "%s>>>>%s STOP AT %02x", _XRED_, _XWHITE_, blockNum);
|
DbprintfEx(FLAG_NEWLINE, "%s>>>>%s STOP AT %02x", _XRED_, _XWHITE_, blockNum);
|
||||||
|
@ -962,14 +927,9 @@ void saMifareMakeTag(void) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
cjSetCursFRight();
|
cjSetCursFRight();
|
||||||
|
|
||||||
DbprintfEx(FLAG_NEWLINE, "%s>>>>>>>> END <<<<<<<<%s", _XYELLOW_, _XWHITE_);
|
DbprintfEx(FLAG_NEWLINE, "%s>>>>>>>> END <<<<<<<<%s", _XYELLOW_, _XWHITE_);
|
||||||
// break;
|
|
||||||
/*if (cfail == 1) {
|
|
||||||
DbprintfEx(FLAG_RAWPRINT,"FATAL: E_MF_HARA_KIRI_\r\n");
|
|
||||||
break;
|
|
||||||
} */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cfail == 0) {
|
if (cfail == 0) {
|
||||||
SpinUp(50);
|
SpinUp(50);
|
||||||
SpinUp(50);
|
SpinUp(50);
|
||||||
|
|
|
@ -49,19 +49,16 @@ on a blank card.
|
||||||
#include "mifaresim.h" // mifare1ksim
|
#include "mifaresim.h" // mifare1ksim
|
||||||
#include "mifareutil.h"
|
#include "mifareutil.h"
|
||||||
|
|
||||||
uint8_t uid[10];
|
static uint8_t uid[10];
|
||||||
uint32_t cuid;
|
static uint32_t cuid;
|
||||||
iso14a_card_select_t p_card;
|
static iso14a_card_select_t p_card;
|
||||||
|
|
||||||
/*
|
// Pseudo-configuration block.
|
||||||
Pseudo-configuration block.
|
static bool printKeys = false; // Prints keys
|
||||||
*/
|
static bool transferToEml = true; // Transfer keys to emulator memory
|
||||||
bool printKeys = false; // Prints keys
|
static bool ecfill = true; // Fill emulator memory with cards content.
|
||||||
bool transferToEml = true; // Transfer keys to emulator memory
|
static bool simulation = true; // Simulates an exact copy of the target tag
|
||||||
bool ecfill = true; // Fill emulator memory with cards content.
|
static bool fillFromEmulator = false; // Dump emulator memory.
|
||||||
bool simulation = true; // Simulates an exact copy of the target tag
|
|
||||||
bool fillFromEmulator = false; // Dump emulator memory.
|
|
||||||
uint8_t stKeyBlock = 20; // Set the quantity of keys in the block.
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Matt's StandAlone mod.
|
// Matt's StandAlone mod.
|
||||||
|
@ -179,7 +176,8 @@ static int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_
|
||||||
|
|
||||||
/* the chk function is a piwi’ed(tm) check that will try all keys for
|
/* the chk function is a piwi’ed(tm) check that will try all keys for
|
||||||
a particular sector. also no tracing no dbg */
|
a particular sector. also no tracing no dbg */
|
||||||
static int saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, uint8_t keyCount, uint8_t *datain, uint64_t *key) {
|
static int saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace,
|
||||||
|
uint8_t keyCount, uint8_t *datain, uint64_t *key) {
|
||||||
DBGLEVEL = DBG_NONE;
|
DBGLEVEL = DBG_NONE;
|
||||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||||
set_tracing(false);
|
set_tracing(false);
|
||||||
|
@ -188,13 +186,15 @@ static int saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, ui
|
||||||
struct Crypto1State *pcs;
|
struct Crypto1State *pcs;
|
||||||
pcs = &mpcs;
|
pcs = &mpcs;
|
||||||
|
|
||||||
for (int i = 0; i < keyCount; ++i) {
|
int retval = -1;
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < keyCount; i++) {
|
||||||
|
|
||||||
/* no need for anticollision. just verify tag is still here */
|
/* no need for anticollision. just verify tag is still here */
|
||||||
// if (!iso14443a_fast_select_card(cjuid, 0)) {
|
// if (!iso14443a_fast_select_card(cjuid, 0)) {
|
||||||
if (!iso14443a_select_card(uid, &p_card, &cuid, true, 0, true)) {
|
if (!iso14443a_select_card(uid, &p_card, &cuid, true, 0, true)) {
|
||||||
DbprintfEx(FLAG_NEWLINE, "FATAL : E_MF_LOSTTAG");
|
DbprintfEx(FLAG_NEWLINE, "FATAL : E_MF_LOSTTAG");
|
||||||
return -1;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t ui64Key = bytes_to_num(datain + i * 6, 6);
|
uint64_t ui64Key = bytes_to_num(datain + i * 6, 6);
|
||||||
|
@ -205,45 +205,111 @@ static int saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, ui
|
||||||
SpinDelayUs(AUTHENTICATION_TIMEOUT);
|
SpinDelayUs(AUTHENTICATION_TIMEOUT);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
crypto1_deinit(pcs);
|
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
|
||||||
*key = ui64Key;
|
*key = ui64Key;
|
||||||
return i;
|
retval = i;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
crypto1_deinit(pcs);
|
crypto1_deinit(pcs);
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
|
return retval;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Abusive microgain on original MifareECardLoad :
|
||||||
|
* - *datain used as error return
|
||||||
|
* - tracing is falsed
|
||||||
|
*/
|
||||||
|
static int saMifareECardLoad(uint32_t numofsectors, uint8_t keytype) {
|
||||||
|
DBGLEVEL = DBG_NONE;
|
||||||
|
|
||||||
|
uint8_t numSectors = numofsectors;
|
||||||
|
uint8_t keyType = keytype;
|
||||||
|
|
||||||
|
struct Crypto1State mpcs = {0, 0};
|
||||||
|
struct Crypto1State *pcs;
|
||||||
|
pcs = &mpcs;
|
||||||
|
|
||||||
|
uint8_t dataoutbuf[16];
|
||||||
|
uint8_t dataoutbuf2[16];
|
||||||
|
|
||||||
|
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||||
|
clear_trace();
|
||||||
|
set_tracing(false);
|
||||||
|
|
||||||
|
int retval = PM3_SUCCESS;
|
||||||
|
|
||||||
|
if (!iso14443a_select_card(uid, &p_card, &cuid, true, 0, true)) {
|
||||||
|
retval = PM3_ESOFT;
|
||||||
|
DbprintfEx(FLAG_RAWPRINT, "Can't select card");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint8_t s = 0; s < numSectors; s++) {
|
||||||
|
uint64_t ui64Key = emlGetKey(s, keyType);
|
||||||
|
if (s == 0) {
|
||||||
|
if (mifare_classic_auth(pcs, cuid, FirstBlockOfSector(s), keyType, ui64Key, AUTH_FIRST)) {
|
||||||
|
retval = PM3_ESOFT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (mifare_classic_auth(pcs, cuid, FirstBlockOfSector(s), keyType, ui64Key, AUTH_NESTED)) {
|
||||||
|
retval = PM3_ESOFT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// failure to read one block, skips to next sector.
|
||||||
|
for (uint8_t blockNo = 0; blockNo < NumBlocksPerSector(s); blockNo++) {
|
||||||
|
if (mifare_classic_readblock(pcs, cuid, FirstBlockOfSector(s) + blockNo, dataoutbuf)) {
|
||||||
|
retval = PM3_ESOFT;
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (blockNo < NumBlocksPerSector(s) - 1) {
|
||||||
|
emlSetMem(dataoutbuf, FirstBlockOfSector(s) + blockNo, 1);
|
||||||
|
} else {
|
||||||
|
// sector trailer, keep the keys, set only the AC
|
||||||
|
emlGetMem(dataoutbuf2, FirstBlockOfSector(s) + blockNo, 1);
|
||||||
|
memcpy(&dataoutbuf2[6], &dataoutbuf[6], 4);
|
||||||
|
emlSetMem(dataoutbuf2, FirstBlockOfSector(s) + blockNo, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int res = mifare_classic_halt(pcs, cuid);
|
||||||
|
(void)res;
|
||||||
|
|
||||||
|
out:
|
||||||
|
crypto1_deinit(pcs);
|
||||||
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void ModInfo(void) {
|
void ModInfo(void) {
|
||||||
DbpString(" HF Mifare sniff/clone - aka MattyRun (Matías A. Ré Medina)");
|
DbpString(" HF Mifare sniff/clone - aka MattyRun (Matías A. Ré Medina)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
It will check if the keys from the attacked tag are a subset from
|
||||||
|
the hardcoded set of keys inside of the ARM. If this is the case
|
||||||
|
then it will load the keys into the emulator memory and also the
|
||||||
|
content of the victim tag, to finally simulate it.
|
||||||
|
|
||||||
|
Alternatively, it can be dumped into a blank card.
|
||||||
|
|
||||||
|
This source code has been tested only in Mifare 1k.
|
||||||
|
|
||||||
|
If you're using the proxmark connected to a device that has an OS, and you're not using the proxmark3 client to see the debug
|
||||||
|
messages, you MUST uncomment usb_disable().
|
||||||
|
*/
|
||||||
void RunMod(void) {
|
void RunMod(void) {
|
||||||
StandAloneMode();
|
StandAloneMode();
|
||||||
Dbprintf(">> Matty mifare chk/dump/sim a.k.a MattyRun Started <<");
|
|
||||||
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
||||||
|
Dbprintf(">> Matty mifare chk/dump/sim a.k.a MattyRun Started <<");
|
||||||
/*
|
|
||||||
It will check if the keys from the attacked tag are a subset from
|
|
||||||
the hardcoded set of keys inside of the ARM. If this is the case
|
|
||||||
then it will load the keys into the emulator memory and also the
|
|
||||||
content of the victim tag, to finally simulate it.
|
|
||||||
|
|
||||||
Alternatively, it can be dumped into a blank card.
|
|
||||||
|
|
||||||
This source code has been tested only in Mifare 1k.
|
|
||||||
|
|
||||||
If you're using the proxmark connected to a device that has an OS, and you're not using the proxmark3 client to see the debug
|
|
||||||
messages, you MUST uncomment usb_disable().
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Comment this line below if you want to see debug messages.
|
// Comment this line below if you want to see debug messages.
|
||||||
// usb_disable();
|
// usb_disable();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint16_t mifare_size = 1024; // Mifare 1k (only 1k supported for now)
|
uint16_t mifare_size = 1024; // Mifare 1k (only 1k supported for now)
|
||||||
uint8_t sectorSize = 64; // 1k's sector size is 64 bytes.
|
uint8_t sectorSize = 64; // 1k's sector size is 64 bytes.
|
||||||
uint8_t blockNo = 3; // Security block is number 3 for each sector.
|
uint8_t blockNo = 3; // Security block is number 3 for each sector.
|
||||||
|
@ -252,9 +318,7 @@ void RunMod(void) {
|
||||||
uint8_t *keyBlock; // Where the keys will be held in memory.
|
uint8_t *keyBlock; // Where the keys will be held in memory.
|
||||||
bool keyFound = false;
|
bool keyFound = false;
|
||||||
|
|
||||||
/*
|
// Set of keys to be used.
|
||||||
Set of keys to be used.
|
|
||||||
*/
|
|
||||||
uint64_t mfKeys[] = {
|
uint64_t mfKeys[] = {
|
||||||
0xffffffffffff, // Default key
|
0xffffffffffff, // Default key
|
||||||
0x000000000000, // Blank key
|
0x000000000000, // Blank key
|
||||||
|
@ -269,22 +333,73 @@ void RunMod(void) {
|
||||||
0xa0478cc39091,
|
0xa0478cc39091,
|
||||||
0x533cb6c723f6,
|
0x533cb6c723f6,
|
||||||
0x8fd0a4f256e9,
|
0x8fd0a4f256e9,
|
||||||
|
0x484558414354, // INFINEONON A / 0F SEC B / INTRATONE / HEXACT...
|
||||||
|
0x414c41524f4e, // ALARON NORALSY
|
||||||
|
0x424c41524f4e, // BLARON NORALSY
|
||||||
|
0x4a6352684677, // COMELIT A General Key / 08 [2] 004
|
||||||
|
0x536653644c65, // COMELIT B General Key / 08 [2] 004
|
||||||
|
0x8829da9daf76, // URMET CAPTIV IF A => ALL A/B / BTICINO
|
||||||
|
0x314B49474956, // "1KIGIV" VIGIK'S SERVICE BADGE A KEY
|
||||||
|
0x021209197591, // BTCINO UNDETERMINED SPREAKD 0x01->0x13 key
|
||||||
|
0x010203040506, // VIGIK's B Derivative
|
||||||
|
0xa22ae129c013, // INFINEON B 00
|
||||||
|
0x49fae4e3849f, // INFINEON B 01
|
||||||
|
0x38fcf33072e0, // INFINEON B 02
|
||||||
|
0x8ad5517b4b18, // INFINEON B 03
|
||||||
|
0x509359f131b1, // INFINEON B 04
|
||||||
|
0x6c78928e1317, // INFINEON B 05
|
||||||
|
0xaa0720018738, // INFINEON B 06
|
||||||
|
0xa6cac2886412, // INFINEON B 07
|
||||||
|
0x62d0c424ed8e, // INFINEON B 08
|
||||||
|
0xe64a986a5d94, // INFINEON B 09
|
||||||
|
0x8fa1d601d0a2, // INFINEON B 0A
|
||||||
|
0x89347350bd36, // INFINEON B 0B
|
||||||
|
0x66d2b7dc39ef, // INFINEON B 0C
|
||||||
|
0x6bc1e1ae547d, // INFINEON B 0D
|
||||||
|
0x22729a9bd40f, // INFINEON B 0E
|
||||||
|
0xd2ece8b9395e, // lib / Nat Bieb
|
||||||
|
0x1494E81663D7, // # NSCP default key
|
||||||
|
0x569369c5a0e5, // # kiev
|
||||||
|
0x632193be1c3c, // # kiev
|
||||||
|
0x644672bd4afe, // # kiev
|
||||||
|
0x8fe644038790, // # kiev
|
||||||
|
0x9de89e070277, // # kiev
|
||||||
|
0xb5ff67cba951, // # kiev / ov-chipkaart
|
||||||
|
0xeff603e1efe9, // # kiev
|
||||||
|
0xf14ee7cae863, // # kiev
|
||||||
|
0xfc00018778f7, // # Västtrafiken KeyA, RKF ÖstgötaTrafiken KeyA
|
||||||
|
0x0297927c0f77, // # Västtrafiken KeyA
|
||||||
|
0x54726176656c, // # Västtrafiken KeyA
|
||||||
|
0x00000ffe2488, // # Västtrafiken KeyB
|
||||||
|
0x776974687573, // # Västtrafiken KeyB
|
||||||
|
0xee0042f88840, // # Västtrafiken KeyB
|
||||||
|
0x26940b21ff5d, // # RKF SLKeyA
|
||||||
|
0xa64598a77478, // # RKF SLKeyA
|
||||||
|
0x5c598c9c58b5, // # RKF SLKeyB
|
||||||
|
0xe4d2770a89be, // # RKF SLKeyB
|
||||||
|
0x722bfcc5375f, // # RKF RejskortDanmark KeyA
|
||||||
|
0xf1d83f964314, // # RKF RejskortDanmark KeyB
|
||||||
|
0x505249564141, // # RKF JOJOPRIVAKeyA
|
||||||
|
0x505249564142, // # RKF JOJOPRIVAKeyB
|
||||||
|
0x47524f555041, // # RKF JOJOGROUPKeyA
|
||||||
|
0x47524f555042, // # RKF JOJOGROUPKeyB
|
||||||
|
0x434f4d4d4f41, // # RKF JOJOGROUPKeyA
|
||||||
|
0x434f4d4d4f42, // # RKF JOJOGROUPKeyB
|
||||||
|
0x4b0b20107ccb, // # TNP3xxx
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This part allocates the byte representation of the
|
This part allocates the byte representation of the
|
||||||
keys in keyBlock's memory space .
|
keys in keyBlock's memory space .
|
||||||
*/
|
*/
|
||||||
keyBlock = BigBuf_malloc(stKeyBlock * 6);
|
keyBlock = BigBuf_malloc(ARRAYLEN(mfKeys) * 6);
|
||||||
int mfKeysCnt = ARRAYLEN(mfKeys);
|
int mfKeysCnt = ARRAYLEN(mfKeys);
|
||||||
|
|
||||||
for (int mfKeyCounter = 0; mfKeyCounter < mfKeysCnt; mfKeyCounter++) {
|
for (int mfKeyCounter = 0; mfKeyCounter < mfKeysCnt; mfKeyCounter++) {
|
||||||
num_to_bytes(mfKeys[mfKeyCounter], 6, (uint8_t *)(keyBlock + mfKeyCounter * 6));
|
num_to_bytes(mfKeys[mfKeyCounter], 6, (uint8_t *)(keyBlock + mfKeyCounter * 6));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Pretty print of the keys to be checked.
|
||||||
Pretty print of the keys to be checked.
|
|
||||||
*/
|
|
||||||
if (printKeys) {
|
if (printKeys) {
|
||||||
Dbprintf("[+] Printing mf keys");
|
Dbprintf("[+] Printing mf keys");
|
||||||
for (uint8_t keycnt = 0; keycnt < mfKeysCnt; keycnt++)
|
for (uint8_t keycnt = 0; keycnt < mfKeysCnt; keycnt++)
|
||||||
|
@ -301,18 +416,19 @@ void RunMod(void) {
|
||||||
*/
|
*/
|
||||||
bool validKey[2][40];
|
bool validKey[2][40];
|
||||||
uint8_t foundKey[2][40][6];
|
uint8_t foundKey[2][40][6];
|
||||||
for (uint16_t t = 0; t < 2; t++) {
|
for (uint8_t i = 0; i < 2; i++) {
|
||||||
for (uint16_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) {
|
for (uint16_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) {
|
||||||
validKey[t][sectorNo] = false;
|
validKey[i][sectorNo] = false;
|
||||||
for (uint16_t i = 0; i < 6; i++) {
|
foundKey[i][sectorNo][0] = 0xFF;
|
||||||
foundKey[t][sectorNo][i] = 0xff;
|
foundKey[i][sectorNo][1] = 0xFF;
|
||||||
}
|
foundKey[i][sectorNo][2] = 0xFF;
|
||||||
|
foundKey[i][sectorNo][3] = 0xFF;
|
||||||
|
foundKey[i][sectorNo][4] = 0xFF;
|
||||||
|
foundKey[i][sectorNo][5] = 0xFF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Iterates through each sector checking if there is a correct key.
|
||||||
Iterates through each sector checking if there is a correct key.
|
|
||||||
*/
|
|
||||||
bool err = 0;
|
bool err = 0;
|
||||||
bool allKeysFound = true;
|
bool allKeysFound = true;
|
||||||
uint32_t size = mfKeysCnt;
|
uint32_t size = mfKeysCnt;
|
||||||
|
@ -324,7 +440,7 @@ void RunMod(void) {
|
||||||
int key = saMifareChkKeys(block, type, true, size, &keyBlock[0], &key64);
|
int key = saMifareChkKeys(block, type, true, size, &keyBlock[0], &key64);
|
||||||
if (key == -1) {
|
if (key == -1) {
|
||||||
LED(LED_RED, 50);
|
LED(LED_RED, 50);
|
||||||
Dbprintf("\t✕ Key not found for this sector!");
|
Dbprintf("\t [✕] Key not found for this sector!");
|
||||||
allKeysFound = false;
|
allKeysFound = false;
|
||||||
// break;
|
// break;
|
||||||
} else if (key == -2) {
|
} else if (key == -2) {
|
||||||
|
@ -334,7 +450,7 @@ void RunMod(void) {
|
||||||
num_to_bytes(key64, 6, foundKey[type][sec]);
|
num_to_bytes(key64, 6, foundKey[type][sec]);
|
||||||
validKey[type][sec] = true;
|
validKey[type][sec] = true;
|
||||||
keyFound = true;
|
keyFound = true;
|
||||||
Dbprintf("\t✓ Found valid key: [%02x%02x%02x%02x%02x%02x]\n",
|
Dbprintf("\t [✓] Found valid key: [%02x%02x%02x%02x%02x%02x]\n",
|
||||||
(keyBlock + 6 * key)[0], (keyBlock + 6 * key)[1], (keyBlock + 6 * key)[2],
|
(keyBlock + 6 * key)[0], (keyBlock + 6 * key)[1], (keyBlock + 6 * key)[2],
|
||||||
(keyBlock + 6 * key)[3], (keyBlock + 6 * key)[4], (keyBlock + 6 * key)[5]
|
(keyBlock + 6 * key)[3], (keyBlock + 6 * key)[4], (keyBlock + 6 * key)[5]
|
||||||
);
|
);
|
||||||
|
@ -371,8 +487,9 @@ void RunMod(void) {
|
||||||
emlClearMem();
|
emlClearMem();
|
||||||
|
|
||||||
uint8_t mblock[16];
|
uint8_t mblock[16];
|
||||||
for (uint16_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) {
|
for (uint8_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) {
|
||||||
if (validKey[0][sectorNo] || validKey[1][sectorNo]) {
|
if (validKey[0][sectorNo] || validKey[1][sectorNo]) {
|
||||||
|
|
||||||
emlGetMem(mblock, FirstBlockOfSector(sectorNo) + NumBlocksPerSector(sectorNo) - 1, 1); // data, block num, blocks count (max 4)
|
emlGetMem(mblock, FirstBlockOfSector(sectorNo) + NumBlocksPerSector(sectorNo) - 1, 1); // data, block num, blocks count (max 4)
|
||||||
for (uint16_t t = 0; t < 2; t++) {
|
for (uint16_t t = 0; t < 2; t++) {
|
||||||
if (validKey[t][sectorNo]) {
|
if (validKey[t][sectorNo]) {
|
||||||
|
@ -382,47 +499,40 @@ void RunMod(void) {
|
||||||
emlSetMem(mblock, FirstBlockOfSector(sectorNo) + NumBlocksPerSector(sectorNo) - 1, 1);
|
emlSetMem(mblock, FirstBlockOfSector(sectorNo) + NumBlocksPerSector(sectorNo) - 1, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Dbprintf("\t✓ Found keys have been transferred to the emulator memory.");
|
|
||||||
|
Dbprintf("\t [✓] Found keys have been transferred to the emulator memory.");
|
||||||
|
|
||||||
if (ecfill) {
|
if (ecfill) {
|
||||||
int filled;
|
int filled;
|
||||||
Dbprintf("\tFilling in with key A.");
|
Dbprintf("\tFilling in with key A.");
|
||||||
filled = MifareECardLoad(sectorsCnt, 0);
|
|
||||||
if (filled != PM3_SUCCESS) {
|
|
||||||
Dbprintf("\t✕ Failed filling with A.");
|
|
||||||
}
|
|
||||||
|
|
||||||
Dbprintf("\tFilling in with key B.");
|
filled = saMifareECardLoad(sectorsCnt, 0);
|
||||||
filled = MifareECardLoad(sectorsCnt, 1);
|
|
||||||
if (filled != PM3_SUCCESS) {
|
if (filled != PM3_SUCCESS) {
|
||||||
Dbprintf("\t✕ Failed filling with B.");
|
|
||||||
|
Dbprintf("\t [✕] Failed filling with A.");
|
||||||
|
Dbprintf("\tFilling in with key B.");
|
||||||
|
filled = saMifareECardLoad(sectorsCnt, 1);
|
||||||
|
if (filled != PM3_SUCCESS) {
|
||||||
|
Dbprintf("\t [✕] Failed filling with B.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((filled == PM3_SUCCESS) && simulation) {
|
if ((filled == PM3_SUCCESS) && simulation) {
|
||||||
Dbprintf("\t✓ Emulator memory filled, simulation started.");
|
Dbprintf("\t [✓] Emulator memory filled, simulation started.");
|
||||||
|
|
||||||
// This will tell the fpga to emulate using previous keys and current target tag content.
|
// This will tell the fpga to emulate using previous keys and current target tag content.
|
||||||
Dbprintf("\t Press button to abort simulation at anytime.");
|
Dbprintf("\t Press button to abort simulation at anytime.");
|
||||||
|
|
||||||
LED_B_ON(); // green
|
LED_B_ON(); // green
|
||||||
// assuming arg0==0, use hardcoded uid 0xdeadbeaf
|
|
||||||
uint16_t simflags;
|
|
||||||
switch (p_card.uidlen) {
|
|
||||||
case 10:
|
|
||||||
simflags = FLAG_10B_UID_IN_DATA;
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
simflags = FLAG_7B_UID_IN_DATA;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
simflags = FLAG_4B_UID_IN_DATA;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
Mifare1ksim(simflags | FLAG_MF_1K, 0, uid, 0, 0);
|
|
||||||
LED_B_OFF();
|
|
||||||
|
|
||||||
/*
|
uint16_t simflags = FLAG_UID_IN_EMUL | FLAG_MF_1K;
|
||||||
Needs further testing.
|
|
||||||
*/
|
SpinOff(1000);
|
||||||
|
Mifare1ksim(simflags, 0, uid, 0, 0);
|
||||||
|
LED_B_OFF();
|
||||||
|
Dbprintf("\t [✓] Simulation ended");
|
||||||
|
|
||||||
|
// Needs further testing.
|
||||||
if (fillFromEmulator) {
|
if (fillFromEmulator) {
|
||||||
uint8_t retry = 5;
|
uint8_t retry = 5;
|
||||||
Dbprintf("\t Trying to dump into blank card.");
|
Dbprintf("\t Trying to dump into blank card.");
|
||||||
|
@ -457,8 +567,10 @@ void RunMod(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
} else if (filled != PM3_SUCCESS) {
|
}
|
||||||
Dbprintf("\t✕ Emulator memory could not be filled due to errors.");
|
|
||||||
|
if (filled != PM3_SUCCESS) {
|
||||||
|
Dbprintf("\t [✕] Emulator memory could not be filled due to errors.");
|
||||||
LED_C_ON();
|
LED_C_ON();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ void ModInfo(void) {
|
||||||
* technologies. Be brave enough to share your knowledge & inspire others. Salvador Mendoza.
|
* technologies. Be brave enough to share your knowledge & inspire others. Salvador Mendoza.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
uint8_t ppdol [255] = {0x80, 0xA8, 0x00, 0x00, 0x02, 0x83, 0x00}; // Default GET PROCESSING
|
static uint8_t ppdol [255] = {0x80, 0xA8, 0x00, 0x00, 0x02, 0x83, 0x00}; // Default GET PROCESSING
|
||||||
|
|
||||||
static uint8_t treatPDOL(uint8_t *apdu) { //Generate GET PROCESSING
|
static uint8_t treatPDOL(uint8_t *apdu) { //Generate GET PROCESSING
|
||||||
uint8_t plen = 7;
|
uint8_t plen = 7;
|
||||||
|
@ -119,7 +119,7 @@ static uint8_t treatPDOL(uint8_t *apdu) { //Generate GET PROCES
|
||||||
|
|
||||||
void RunMod(void) {
|
void RunMod(void) {
|
||||||
StandAloneMode();
|
StandAloneMode();
|
||||||
Dbprintf(_YELLOW_(">>") "Reading Visa cards & Emulating a Visa MSD Transaction a.k.a. MSDSal Started<<");
|
DbpString(_YELLOW_(">>") "Reading Visa cards & Emulating a Visa MSD Transaction a.k.a. MSDSal Started " _YELLOW_("<<"));
|
||||||
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
||||||
|
|
||||||
//For reading process
|
//For reading process
|
||||||
|
@ -206,10 +206,10 @@ void RunMod(void) {
|
||||||
//Checking if the user wants to go directly to emulation mode using a hardcoded track 2
|
//Checking if the user wants to go directly to emulation mode using a hardcoded track 2
|
||||||
if (chktoken == true && token[0] != 0x00) {
|
if (chktoken == true && token[0] != 0x00) {
|
||||||
state = STATE_EMU;
|
state = STATE_EMU;
|
||||||
Dbprintf(_YELLOW_("[") "Initialized emulation mode " _YELLOW_("]"));
|
DbpString(_YELLOW_("[ ") "Initialized emulation mode" _YELLOW_(" ]"));
|
||||||
DbpString("\n"_YELLOW_("!!") "Waiting for a card reader...");
|
DbpString("\n"_YELLOW_("!!") "Waiting for a card reader...");
|
||||||
} else {
|
} else {
|
||||||
DbpString(_YELLOW_("[") "Initialized reading mode " _YELLOW_("]"));
|
DbpString(_YELLOW_("[ ") "Initialized reading mode" _YELLOW_(" ]"));
|
||||||
DbpString("\n"_YELLOW_("!!") "Waiting for a Visa card...");
|
DbpString("\n"_YELLOW_("!!") "Waiting for a Visa card...");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,12 +228,12 @@ void RunMod(void) {
|
||||||
if (state == STATE_READ) {
|
if (state == STATE_READ) {
|
||||||
if (chktoken == true && token[0] != 0x00) { //Only change to emulation if it saved a track 2 in memory
|
if (chktoken == true && token[0] != 0x00) { //Only change to emulation if it saved a track 2 in memory
|
||||||
state = STATE_EMU;
|
state = STATE_EMU;
|
||||||
Dbprintf(_YELLOW_("[") "In emulation mode " _YELLOW_("]"));
|
DbpString(_YELLOW_("[ ") "In emulation mode" _YELLOW_(" ]"));
|
||||||
} else
|
} else
|
||||||
Dbprintf(_YELLOW_("!!") "Nothing in memory to emulate");
|
DbpString(_YELLOW_("!!") "Nothing in memory to emulate");
|
||||||
} else {
|
} else {
|
||||||
state = STATE_READ;
|
state = STATE_READ;
|
||||||
Dbprintf(_YELLOW_("[") "In reading mode " _YELLOW_("]"));
|
DbpString(_YELLOW_("[ ") "In reading mode" _YELLOW_(" ]"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,7 +248,7 @@ void RunMod(void) {
|
||||||
|
|
||||||
if (iso14443a_select_card(NULL, &card_a_info, NULL, true, 0, false)) {
|
if (iso14443a_select_card(NULL, &card_a_info, NULL, true, 0, false)) {
|
||||||
|
|
||||||
Dbprintf(_YELLOW_("+") "Found ISO 14443 Type A!");
|
DbpString(_YELLOW_("+") "Found ISO 14443 Type A!");
|
||||||
|
|
||||||
for (uint8_t i = 0; i < 4; i++) {
|
for (uint8_t i = 0; i < 4; i++) {
|
||||||
chktoken = false;
|
chktoken = false;
|
||||||
|
@ -257,11 +257,11 @@ void RunMod(void) {
|
||||||
uint8_t apdulen = iso14_apdu(apdus[i], (uint16_t) apdusLen[i], false, apdubuffer, NULL);
|
uint8_t apdulen = iso14_apdu(apdus[i], (uint16_t) apdusLen[i], false, apdubuffer, NULL);
|
||||||
|
|
||||||
if (apdulen > 0) {
|
if (apdulen > 0) {
|
||||||
Dbprintf(_YELLOW_("[") "Proxmark command " _YELLOW_("]"));
|
DbpString(_YELLOW_("[ ") "Proxmark command" _YELLOW_(" ]"));
|
||||||
Dbhexdump(apdusLen[i], apdus[i], false);
|
Dbhexdump(apdusLen[i], apdus[i], false);
|
||||||
Dbprintf(_GREEN_("[") "Card answer " _GREEN_("]"));
|
DbpString(_GREEN_("[ ") "Card answer" _GREEN_(" ]"));
|
||||||
Dbhexdump(apdulen - 2, apdubuffer, false);
|
Dbhexdump(apdulen - 2, apdubuffer, false);
|
||||||
Dbprintf("----");
|
DbpString("----");
|
||||||
|
|
||||||
for (uint8_t u = 0; u < apdulen; u++) {
|
for (uint8_t u = 0; u < apdulen; u++) {
|
||||||
if (i == 1) {
|
if (i == 1) {
|
||||||
|
@ -284,24 +284,24 @@ void RunMod(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == 1) {
|
if (i == 1) {
|
||||||
Dbprintf(_GREEN_("[") "Challenge generated " _GREEN_("]"));
|
DbpString(_GREEN_("[ ") "Challenge generated" _GREEN_(" ]"));
|
||||||
Dbhexdump(plen, existpdol ? ppdol : processing, false);
|
Dbhexdump(plen, existpdol ? ppdol : processing, false);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Dbprintf(_YELLOW_("!!") "Error reading the card");
|
DbpString(_YELLOW_("!!") "Error reading the card");
|
||||||
}
|
}
|
||||||
LED_B_OFF();
|
LED_B_OFF();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chktoken) {
|
if (chktoken) {
|
||||||
Dbprintf(_RED_("[") "Track 2 " _RED_("]"));
|
DbpString(_RED_("[ ") "Track 2" _RED_(" ]"));
|
||||||
Dbhexdump(19, (uint8_t *)token, false);
|
Dbhexdump(19, (uint8_t *)token, false);
|
||||||
Dbprintf(_YELLOW_("!!") "Card number");
|
DbpString(_YELLOW_("!!") "Card number");
|
||||||
Dbhexdump(8, (uint8_t *)token, false);
|
Dbhexdump(8, (uint8_t *)token, false);
|
||||||
DbpString("---");
|
DbpString("---");
|
||||||
LED_C_ON();
|
LED_C_ON();
|
||||||
state = STATE_EMU;
|
state = STATE_EMU;
|
||||||
Dbprintf(_YELLOW_("[") "Initialized emulation mode " _YELLOW_("]"));
|
DbpString(_YELLOW_("[ ") "Initialized emulation mode" _YELLOW_(" ]"));
|
||||||
DbpString("\n"_YELLOW_("!!") "Waiting for a card reader...");
|
DbpString("\n"_YELLOW_("!!") "Waiting for a card reader...");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -318,7 +318,7 @@ void RunMod(void) {
|
||||||
DbpString(_YELLOW_("!!") "Error initializing the emulation process!");
|
DbpString(_YELLOW_("!!") "Error initializing the emulation process!");
|
||||||
SpinDelay(500);
|
SpinDelay(500);
|
||||||
state = STATE_READ;
|
state = STATE_READ;
|
||||||
DbpString(_YELLOW_("[") "Initialized reading mode " _YELLOW_("]"));
|
DbpString(_YELLOW_("[ ") "Initialized reading mode" _YELLOW_(" ]"));
|
||||||
DbpString("\n" _YELLOW_("!!") "Waiting for a Visa card...");
|
DbpString("\n" _YELLOW_("!!") "Waiting for a Visa card...");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -336,7 +336,7 @@ void RunMod(void) {
|
||||||
LED_B_OFF();
|
LED_B_OFF();
|
||||||
// Clean receive command buffer
|
// Clean receive command buffer
|
||||||
if (!GetIso14443aCommandFromReader(receivedCmd, receivedCmdPar, &len)) {
|
if (!GetIso14443aCommandFromReader(receivedCmd, receivedCmdPar, &len)) {
|
||||||
Dbprintf(_YELLOW_("!!") "Emulator stopped");
|
DbpString(_YELLOW_("!!") "Emulator stopped");
|
||||||
retval = PM3_EOPABORTED;
|
retval = PM3_EOPABORTED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -367,7 +367,7 @@ void RunMod(void) {
|
||||||
DbpString(_YELLOW_("+") "Request for RATS");
|
DbpString(_YELLOW_("+") "Request for RATS");
|
||||||
p_response = &responses[RATS];
|
p_response = &responses[RATS];
|
||||||
} else {
|
} else {
|
||||||
Dbprintf(_YELLOW_("[") "Card reader command " _YELLOW_("]"));
|
DbpString(_YELLOW_("[ ") "Card reader command" _YELLOW_(" ]"));
|
||||||
Dbhexdump(len, receivedCmd, false);
|
Dbhexdump(len, receivedCmd, false);
|
||||||
|
|
||||||
if (receivedCmd[0] == 0x02 || receivedCmd[0] == 0x03) { //Emulate a Visa MSD(Magnetic stripe data) card
|
if (receivedCmd[0] == 0x02 || receivedCmd[0] == 0x03) { //Emulate a Visa MSD(Magnetic stripe data) card
|
||||||
|
@ -408,7 +408,7 @@ void RunMod(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Dbprintf(_YELLOW_("!!") "Received unknown command!");
|
DbpString(_YELLOW_("!!") "Received unknown command!");
|
||||||
if (prevCmd < 4) {
|
if (prevCmd < 4) {
|
||||||
memcpy(dynamic_response_info.response, receivedCmd, len);
|
memcpy(dynamic_response_info.response, receivedCmd, len);
|
||||||
dynamic_response_info.response_n = len;
|
dynamic_response_info.response_n = len;
|
||||||
|
@ -418,9 +418,9 @@ void RunMod(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (dynamic_response_info.response_n > 0) {
|
if (dynamic_response_info.response_n > 0) {
|
||||||
Dbprintf(_GREEN_("[") "Proxmark3 answer " _GREEN_("]"));
|
DbpString(_GREEN_("[ ") "Proxmark3 answer" _GREEN_(" ]"));
|
||||||
Dbhexdump(dynamic_response_info.response_n, dynamic_response_info.response, false);
|
Dbhexdump(dynamic_response_info.response_n, dynamic_response_info.response, false);
|
||||||
Dbprintf("----");
|
DbpString("----");
|
||||||
|
|
||||||
// Add CRC bytes, always used in ISO 14443A-4 compliant cards
|
// Add CRC bytes, always used in ISO 14443A-4 compliant cards
|
||||||
AddCrc14A(dynamic_response_info.response, dynamic_response_info.response_n);
|
AddCrc14A(dynamic_response_info.response, dynamic_response_info.response_n);
|
||||||
|
|
|
@ -151,10 +151,10 @@ void RunMod(void) {
|
||||||
SpinDelay(500);
|
SpinDelay(500);
|
||||||
// Begin clone function here:
|
// Begin clone function here:
|
||||||
/* Example from client/mifarehost.c for commanding a block write for "magic Chinese" cards:
|
/* Example from client/mifarehost.c for commanding a block write for "magic Chinese" cards:
|
||||||
SendCommandOLD(CMD_HF_MIFARE_CSETBL, params & (0xFE | (uid == NULL ? 0:1)), blockNo, 0, data, 16);
|
SendCommandMIX(CMD_HF_MIFARE_CSETBL, params & (0xFE | (uid == NULL ? 0:1)), blockNo, 0, data, 16);
|
||||||
|
|
||||||
Block read is similar:
|
Block read is similar:
|
||||||
SendCommandOLD(CMD_HF_MIFARE_CGETBL, params, blockNo, 0,...};
|
SendCommandMIX(CMD_HF_MIFARE_CGETBL, params, blockNo, 0,...};
|
||||||
We need to imitate that call with blockNo 0 to set a uid.
|
We need to imitate that call with blockNo 0 to set a uid.
|
||||||
|
|
||||||
The get and set commands are handled in this file:
|
The get and set commands are handled in this file:
|
||||||
|
|
|
@ -25,11 +25,9 @@
|
||||||
|
|
||||||
// low & high - array for storage IDs. Its length must be equal.
|
// low & high - array for storage IDs. Its length must be equal.
|
||||||
// Predefined IDs must be stored in low[].
|
// Predefined IDs must be stored in low[].
|
||||||
// In high[] must be nulls
|
static uint64_t low[] = {0x565A1140BE, 0x365A398149, 0x5555555555, 0xFFFFFFFFFF};
|
||||||
uint64_t low[] = {0x565A1140BE, 0x365A398149, 0x5555555555, 0xFFFFFFFFFF};
|
static uint8_t *bba, slots_count;
|
||||||
uint32_t high[] = {0, 0, 0, 0};
|
static int buflen;
|
||||||
uint8_t *bba, slots_count;
|
|
||||||
int buflen;
|
|
||||||
|
|
||||||
void ModInfo(void) {
|
void ModInfo(void) {
|
||||||
DbpString(" LF EM4100 simulator standalone mode");
|
DbpString(" LF EM4100 simulator standalone mode");
|
||||||
|
|
|
@ -39,10 +39,10 @@
|
||||||
// low & high - array for storage IDs. Its length must be equal.
|
// low & high - array for storage IDs. Its length must be equal.
|
||||||
// Predefined IDs must be stored in low[].
|
// Predefined IDs must be stored in low[].
|
||||||
// In high[] must be nulls
|
// In high[] must be nulls
|
||||||
uint64_t low[] = {0x565AF781C7, 0x540053E4E2, 0x1234567890, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
static uint64_t low[] = {0x565AF781C7, 0x540053E4E2, 0x1234567890, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||||
uint32_t high[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
static uint32_t high[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||||
uint8_t *bba, slots_count;
|
static uint8_t *bba, slots_count;
|
||||||
int buflen;
|
static int buflen;
|
||||||
|
|
||||||
void ModInfo(void) {
|
void ModInfo(void) {
|
||||||
DbpString(" LF EM4100 read/write/clone mode");
|
DbpString(" LF EM4100 read/write/clone mode");
|
||||||
|
@ -161,7 +161,7 @@ void RunMod(void) {
|
||||||
state = 3;
|
state = 3;
|
||||||
} else if (button_pressed == BUTTON_SINGLE_CLICK) {
|
} else if (button_pressed == BUTTON_SINGLE_CLICK) {
|
||||||
// Click - exit to select mode
|
// Click - exit to select mode
|
||||||
CmdEM410xdemod(1, &high[selected], &low[selected], 0);
|
CmdEM410xdemod(1, &high[selected], &low[selected]);
|
||||||
FlashLEDs(100, 5);
|
FlashLEDs(100, 5);
|
||||||
#ifdef WITH_FLASH
|
#ifdef WITH_FLASH
|
||||||
SaveIDtoFlash(selected, low[selected]);
|
SaveIDtoFlash(selected, low[selected]);
|
||||||
|
|
|
@ -231,7 +231,8 @@ static uint32_t IceHIDDemod(void) {
|
||||||
uint32_t hi2 = 0, hi = 0, lo = 0;
|
uint32_t hi2 = 0, hi = 0, lo = 0;
|
||||||
|
|
||||||
// large enough to catch 2 sequences of largest format
|
// large enough to catch 2 sequences of largest format
|
||||||
size_t size = 50 * 128 * 2; // 12800 bytes
|
// size_t size = 50 * 128 * 2; // 12800 bytes
|
||||||
|
size_t size = MIN(12800, BigBuf_max_traceLen());
|
||||||
//uint8_t *dest = BigBuf_malloc(size);
|
//uint8_t *dest = BigBuf_malloc(size);
|
||||||
uint8_t *dest = BigBuf_get_addr();
|
uint8_t *dest = BigBuf_get_addr();
|
||||||
|
|
||||||
|
@ -350,30 +351,32 @@ void RunMod(void) {
|
||||||
|
|
||||||
uint32_t res;
|
uint32_t res;
|
||||||
|
|
||||||
// since we steal 12800 from bigbuffer, no need to sample it.
|
// since we steal 12800 from bigbuffer, no need to sample it.
|
||||||
DoAcquisition_config(false, 28000);
|
size_t size = MIN(28000, BigBuf_max_traceLen());
|
||||||
|
DoAcquisition_config(false, size);
|
||||||
res = IceHIDDemod();
|
res = IceHIDDemod();
|
||||||
if (res == PM3_SUCCESS) {
|
if (res == PM3_SUCCESS) {
|
||||||
LED_A_OFF();
|
LED_A_OFF();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
DoAcquisition_config(false, 28000);
|
DoAcquisition_config(false, size);
|
||||||
res = IceAWIDdemod();
|
res = IceAWIDdemod();
|
||||||
if (res == PM3_SUCCESS) {
|
if (res == PM3_SUCCESS) {
|
||||||
LED_A_OFF();
|
LED_A_OFF();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
DoAcquisition_config(false, 20000);
|
DoAcquisition_config(false, size);
|
||||||
res = IceEM410xdemod();
|
res = IceIOdemod();
|
||||||
if (res == PM3_SUCCESS) {
|
if (res == PM3_SUCCESS) {
|
||||||
LED_A_OFF();
|
LED_A_OFF();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
DoAcquisition_config(false, 28000);
|
size = MIN(20000, BigBuf_max_traceLen());
|
||||||
res = IceIOdemod();
|
DoAcquisition_config(false, size);
|
||||||
|
res = IceEM410xdemod();
|
||||||
if (res == PM3_SUCCESS) {
|
if (res == PM3_SUCCESS) {
|
||||||
LED_A_OFF();
|
LED_A_OFF();
|
||||||
continue;
|
continue;
|
||||||
|
|
186
armsrc/appmain.c
186
armsrc/appmain.c
|
@ -29,6 +29,7 @@
|
||||||
#include "felica.h"
|
#include "felica.h"
|
||||||
#include "hitag2.h"
|
#include "hitag2.h"
|
||||||
#include "hitagS.h"
|
#include "hitagS.h"
|
||||||
|
#include "em4x50.h"
|
||||||
#include "iclass.h"
|
#include "iclass.h"
|
||||||
#include "legicrfsim.h"
|
#include "legicrfsim.h"
|
||||||
#include "epa.h"
|
#include "epa.h"
|
||||||
|
@ -70,10 +71,14 @@
|
||||||
#define TOSEND_BUFFER_SIZE (9*MAX_FRAME_SIZE + 1 + 1 + 2) // 8 data bits and 1 parity bit per payload byte, 1 correction bit, 1 SOC bit, 2 EOC bits
|
#define TOSEND_BUFFER_SIZE (9*MAX_FRAME_SIZE + 1 + 1 + 2) // 8 data bits and 1 parity bit per payload byte, 1 correction bit, 1 SOC bit, 2 EOC bits
|
||||||
uint8_t ToSend[TOSEND_BUFFER_SIZE];
|
uint8_t ToSend[TOSEND_BUFFER_SIZE];
|
||||||
int ToSendMax = -1;
|
int ToSendMax = -1;
|
||||||
|
|
||||||
|
extern uint32_t _stack_start, _stack_end;
|
||||||
|
|
||||||
|
|
||||||
static int ToSendBit;
|
static int ToSendBit;
|
||||||
struct common_area common_area __attribute__((section(".commonarea")));
|
struct common_area common_area __attribute__((section(".commonarea")));
|
||||||
int button_status = BUTTON_NO_CLICK;
|
static int button_status = BUTTON_NO_CLICK;
|
||||||
bool allow_send_wtx = false;
|
static bool allow_send_wtx = false;
|
||||||
|
|
||||||
inline void send_wtx(uint16_t wtx) {
|
inline void send_wtx(uint16_t wtx) {
|
||||||
if (allow_send_wtx) {
|
if (allow_send_wtx) {
|
||||||
|
@ -106,7 +111,7 @@ void ToSendStuffBit(int b) {
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Read an ADC channel and block till it completes, then return the result
|
// Read an ADC channel and block till it completes, then return the result
|
||||||
// in ADC units (0 to 1023). Also a routine to average 32 samples and
|
// in ADC units (0 to 1023). Also a routine to sum up a number of samples and
|
||||||
// return that.
|
// return that.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
static uint16_t ReadAdc(int ch) {
|
static uint16_t ReadAdc(int ch) {
|
||||||
|
@ -136,12 +141,14 @@ static uint16_t ReadAdc(int ch) {
|
||||||
|
|
||||||
// was static - merlok
|
// was static - merlok
|
||||||
uint16_t AvgAdc(int ch) {
|
uint16_t AvgAdc(int ch) {
|
||||||
uint16_t a = 0;
|
return SumAdc(ch, 32) >> 5;
|
||||||
for (uint8_t i = 0; i < 32; i++)
|
}
|
||||||
a += ReadAdc(ch);
|
|
||||||
|
|
||||||
//division by 32
|
uint16_t SumAdc(int ch, int NbSamples) {
|
||||||
return (a + 15) >> 5;
|
uint16_t a = 0;
|
||||||
|
for (uint8_t i = 0; i < NbSamples; i++)
|
||||||
|
a += ReadAdc(ch);
|
||||||
|
return (a + (NbSamples >> 1) - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MeasureAntennaTuning(void) {
|
static void MeasureAntennaTuning(void) {
|
||||||
|
@ -184,7 +191,7 @@ static void MeasureAntennaTuning(void) {
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, i);
|
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, i);
|
||||||
SpinDelay(20);
|
SpinDelay(20);
|
||||||
uint32_t adcval = ((MAX_ADC_LF_VOLTAGE * AvgAdc(ADC_CHAN_LF)) >> 10);
|
uint32_t adcval = ((MAX_ADC_LF_VOLTAGE * (SumAdc(ADC_CHAN_LF, 32) >> 1)) >> 14);
|
||||||
if (i == LF_DIVISOR_125)
|
if (i == LF_DIVISOR_125)
|
||||||
payload.v_lf125 = adcval; // voltage at 125kHz
|
payload.v_lf125 = adcval; // voltage at 125kHz
|
||||||
|
|
||||||
|
@ -210,9 +217,9 @@ static void MeasureAntennaTuning(void) {
|
||||||
SpinDelay(50);
|
SpinDelay(50);
|
||||||
|
|
||||||
#if defined RDV4
|
#if defined RDV4
|
||||||
payload.v_hf = (MAX_ADC_HF_VOLTAGE_RDV40 * AvgAdc(ADC_CHAN_HF_RDV40)) >> 10;
|
payload.v_hf = (MAX_ADC_HF_VOLTAGE_RDV40 * SumAdc(ADC_CHAN_HF_RDV40, 32)) >> 15;
|
||||||
#else
|
#else
|
||||||
payload.v_hf = (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10;
|
payload.v_hf = (MAX_ADC_HF_VOLTAGE * SumAdc(ADC_CHAN_HF, 32)) >> 15;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
|
@ -224,16 +231,26 @@ static void MeasureAntennaTuning(void) {
|
||||||
static uint16_t MeasureAntennaTuningHfData(void) {
|
static uint16_t MeasureAntennaTuningHfData(void) {
|
||||||
|
|
||||||
#if defined RDV4
|
#if defined RDV4
|
||||||
return (MAX_ADC_HF_VOLTAGE_RDV40 * AvgAdc(ADC_CHAN_HF_RDV40)) >> 10;
|
return (MAX_ADC_HF_VOLTAGE_RDV40 * SumAdc(ADC_CHAN_HF_RDV40, 32)) >> 15;
|
||||||
#else
|
#else
|
||||||
return (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10;
|
return (MAX_ADC_HF_VOLTAGE * SumAdc(ADC_CHAN_HF, 32)) >> 15;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Measure LF in milliVolt
|
// Measure LF in milliVolt
|
||||||
static uint32_t MeasureAntennaTuningLfData(void) {
|
static uint32_t MeasureAntennaTuningLfData(void) {
|
||||||
return (MAX_ADC_LF_VOLTAGE * AvgAdc(ADC_CHAN_LF)) >> 10;
|
return (MAX_ADC_LF_VOLTAGE * (SumAdc(ADC_CHAN_LF, 32) >> 1)) >> 14;
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_stack_usage(void) {
|
||||||
|
// pointer arithmetic is times 4. (two shifts to the left)
|
||||||
|
for (uint32_t *p = &_stack_start; ; ++p) {
|
||||||
|
if (*p != 0xdeadbeef) {
|
||||||
|
Dbprintf(" Max stack usage.........%d / %d bytes", (&_stack_end - p) << 2, (&_stack_end - &_stack_start) << 2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReadMem(int addr) {
|
void ReadMem(int addr) {
|
||||||
|
@ -242,8 +259,7 @@ void ReadMem(int addr) {
|
||||||
Dbprintf("%x: %02x %02x %02x %02x %02x %02x %02x %02x", addr, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]);
|
Dbprintf("%x: %02x %02x %02x %02x %02x %02x %02x %02x", addr, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* osimage version information is linked in */
|
/* osimage version information is linked in, cf commonutil.h */
|
||||||
extern struct version_information version_information;
|
|
||||||
/* bootrom version information is pointed to from _bootphase1_version_pointer */
|
/* bootrom version information is pointed to from _bootphase1_version_pointer */
|
||||||
extern char *_bootphase1_version_pointer, _flash_start, _flash_end, __data_src_start__;
|
extern char *_bootphase1_version_pointer, _flash_start, _flash_end, __data_src_start__;
|
||||||
static void SendVersion(void) {
|
static void SendVersion(void) {
|
||||||
|
@ -256,17 +272,19 @@ static void SendVersion(void) {
|
||||||
*/
|
*/
|
||||||
char *bootrom_version = *(char **)&_bootphase1_version_pointer;
|
char *bootrom_version = *(char **)&_bootphase1_version_pointer;
|
||||||
|
|
||||||
strncat(VersionString, " [ ARM ]\n", sizeof(VersionString) - strlen(VersionString) - 1);
|
strncat(VersionString, " "_YELLOW_("[ ARM ]")"\n", sizeof(VersionString) - strlen(VersionString) - 1);
|
||||||
|
|
||||||
if (bootrom_version < &_flash_start || bootrom_version >= &_flash_end) {
|
if (bootrom_version < &_flash_start || bootrom_version >= &_flash_end) {
|
||||||
strcat(VersionString, "bootrom version information appears invalid\n");
|
strcat(VersionString, "bootrom version information appears invalid\n");
|
||||||
} else {
|
} else {
|
||||||
FormatVersionInformation(temp, sizeof(temp), " bootrom: ", bootrom_version);
|
FormatVersionInformation(temp, sizeof(temp), " bootrom: ", bootrom_version);
|
||||||
strncat(VersionString, temp, sizeof(VersionString) - strlen(VersionString) - 1);
|
strncat(VersionString, temp, sizeof(VersionString) - strlen(VersionString) - 1);
|
||||||
|
strncat(VersionString, "\n", sizeof(VersionString) - strlen(VersionString) - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
FormatVersionInformation(temp, sizeof(temp), " os: ", &version_information);
|
FormatVersionInformation(temp, sizeof(temp), " os: ", &version_information);
|
||||||
strncat(VersionString, temp, sizeof(VersionString) - strlen(VersionString) - 1);
|
strncat(VersionString, temp, sizeof(VersionString) - strlen(VersionString) - 1);
|
||||||
|
strncat(VersionString, "\n", sizeof(VersionString) - strlen(VersionString) - 1);
|
||||||
|
|
||||||
#if defined(__clang__)
|
#if defined(__clang__)
|
||||||
strncat(VersionString, " compiled with Clang/LLVM "__VERSION__"\n", sizeof(VersionString) - strlen(VersionString) - 1);
|
strncat(VersionString, " compiled with Clang/LLVM "__VERSION__"\n", sizeof(VersionString) - strlen(VersionString) - 1);
|
||||||
|
@ -274,11 +292,11 @@ static void SendVersion(void) {
|
||||||
strncat(VersionString, " compiled with GCC "__VERSION__"\n", sizeof(VersionString) - strlen(VersionString) - 1);
|
strncat(VersionString, " compiled with GCC "__VERSION__"\n", sizeof(VersionString) - strlen(VersionString) - 1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
strncat(VersionString, "\n [ FPGA ]\n ", sizeof(VersionString) - strlen(VersionString) - 1);
|
strncat(VersionString, "\n "_YELLOW_("[ FPGA ]")"\n ", sizeof(VersionString) - strlen(VersionString) - 1);
|
||||||
|
|
||||||
for (int i = 0; i < fpga_bitstream_num; i++) {
|
for (int i = 0; i < g_fpga_bitstream_num; i++) {
|
||||||
strncat(VersionString, fpga_version_information[i], sizeof(VersionString) - strlen(VersionString) - 1);
|
strncat(VersionString, g_fpga_version_information[i], sizeof(VersionString) - strlen(VersionString) - 1);
|
||||||
if (i < fpga_bitstream_num - 1) {
|
if (i < g_fpga_bitstream_num - 1) {
|
||||||
strncat(VersionString, "\n ", sizeof(VersionString) - strlen(VersionString) - 1);
|
strncat(VersionString, "\n ", sizeof(VersionString) - strlen(VersionString) - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -313,7 +331,7 @@ static void TimingIntervalAcquisition(void) {
|
||||||
// measure the Connection Speed by sending SpeedTestBufferSize bytes to client and measuring the elapsed time.
|
// measure the Connection Speed by sending SpeedTestBufferSize bytes to client and measuring the elapsed time.
|
||||||
// Note: this mimics GetFromBigbuf(), i.e. we have the overhead of the PacketCommandNG structure included.
|
// Note: this mimics GetFromBigbuf(), i.e. we have the overhead of the PacketCommandNG structure included.
|
||||||
static void printConnSpeed(void) {
|
static void printConnSpeed(void) {
|
||||||
DbpString(_BLUE_("Transfer Speed"));
|
DbpString(_CYAN_("Transfer Speed"));
|
||||||
Dbprintf(" Sending packets to client...");
|
Dbprintf(" Sending packets to client...");
|
||||||
|
|
||||||
#define CONN_SPEED_TEST_MIN_TIME 500 // in milliseconds
|
#define CONN_SPEED_TEST_MIN_TIME 500 // in milliseconds
|
||||||
|
@ -353,7 +371,10 @@ static void SendStatus(void) {
|
||||||
printT55xxConfig(); // LF T55XX Config
|
printT55xxConfig(); // LF T55XX Config
|
||||||
#endif
|
#endif
|
||||||
printConnSpeed();
|
printConnSpeed();
|
||||||
DbpString(_BLUE_("Various"));
|
DbpString(_CYAN_("Various"));
|
||||||
|
|
||||||
|
print_stack_usage();
|
||||||
|
|
||||||
Dbprintf(" DBGLEVEL................%d", DBGLEVEL);
|
Dbprintf(" DBGLEVEL................%d", DBGLEVEL);
|
||||||
Dbprintf(" ToSendMax...............%d", ToSendMax);
|
Dbprintf(" ToSendMax...............%d", ToSendMax);
|
||||||
Dbprintf(" ToSendBit...............%d", ToSendBit);
|
Dbprintf(" ToSendBit...............%d", ToSendBit);
|
||||||
|
@ -372,7 +393,7 @@ static void SendStatus(void) {
|
||||||
Dbprintf(_YELLOW_(" Slow Clock actual speed seems closer to %d kHz"),
|
Dbprintf(_YELLOW_(" Slow Clock actual speed seems closer to %d kHz"),
|
||||||
(16 * MAINCK / 1000) / mainf * delta_time / SLCK_CHECK_MS);
|
(16 * MAINCK / 1000) / mainf * delta_time / SLCK_CHECK_MS);
|
||||||
}
|
}
|
||||||
DbpString(_BLUE_("Installed StandAlone Mode"));
|
DbpString(_CYAN_("Installed StandAlone Mode"));
|
||||||
ModInfo();
|
ModInfo();
|
||||||
|
|
||||||
#ifdef WITH_FLASH
|
#ifdef WITH_FLASH
|
||||||
|
@ -385,12 +406,13 @@ static void SendStatus(void) {
|
||||||
static void SendCapabilities(void) {
|
static void SendCapabilities(void) {
|
||||||
capabilities_t capabilities;
|
capabilities_t capabilities;
|
||||||
capabilities.version = CAPABILITIES_VERSION;
|
capabilities.version = CAPABILITIES_VERSION;
|
||||||
capabilities.via_fpc = reply_via_fpc;
|
capabilities.via_fpc = g_reply_via_fpc;
|
||||||
capabilities.via_usb = reply_via_usb;
|
capabilities.via_usb = g_reply_via_usb;
|
||||||
|
capabilities.bigbuf_size = BigBuf_get_size();
|
||||||
capabilities.baudrate = 0; // no real baudrate for USB-CDC
|
capabilities.baudrate = 0; // no real baudrate for USB-CDC
|
||||||
#ifdef WITH_FPC_USART
|
#ifdef WITH_FPC_USART
|
||||||
if (reply_via_fpc)
|
if (g_reply_via_fpc)
|
||||||
capabilities.baudrate = usart_baudrate;
|
capabilities.baudrate = g_usart_baudrate;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WITH_FLASH
|
#ifdef WITH_FLASH
|
||||||
|
@ -433,6 +455,11 @@ static void SendCapabilities(void) {
|
||||||
#else
|
#else
|
||||||
capabilities.compiled_with_hitag = false;
|
capabilities.compiled_with_hitag = false;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef WITH_EM4x50
|
||||||
|
capabilities.compiled_with_em4x50 = true;
|
||||||
|
#else
|
||||||
|
capabilities.compiled_with_em4x50 = false;
|
||||||
|
#endif
|
||||||
#ifdef WITH_HFSNIFF
|
#ifdef WITH_HFSNIFF
|
||||||
capabilities.compiled_with_hfsniff = true;
|
capabilities.compiled_with_hfsniff = true;
|
||||||
#else
|
#else
|
||||||
|
@ -524,7 +551,7 @@ at the same place! :-)
|
||||||
void ListenReaderField(uint8_t limit) {
|
void ListenReaderField(uint8_t limit) {
|
||||||
#define LF_ONLY 1
|
#define LF_ONLY 1
|
||||||
#define HF_ONLY 2
|
#define HF_ONLY 2
|
||||||
#define REPORT_CHANGE 10 // report new values only if they have changed at least by REPORT_CHANGE
|
#define REPORT_CHANGE 1000 // report new values only if they have changed at least by REPORT_CHANGE mV
|
||||||
|
|
||||||
uint16_t lf_av = 0, lf_av_new, lf_baseline = 0, lf_max = 0;
|
uint16_t lf_av = 0, lf_av_new, lf_baseline = 0, lf_max = 0;
|
||||||
uint16_t hf_av = 0, hf_av_new, hf_baseline = 0, hf_max = 0;
|
uint16_t hf_av = 0, hf_av_new, hf_baseline = 0, hf_max = 0;
|
||||||
|
@ -538,8 +565,8 @@ void ListenReaderField(uint8_t limit) {
|
||||||
LEDsoff();
|
LEDsoff();
|
||||||
|
|
||||||
if (limit == LF_ONLY) {
|
if (limit == LF_ONLY) {
|
||||||
lf_av = lf_max = AvgAdc(ADC_CHAN_LF);
|
lf_av = lf_max = (MAX_ADC_LF_VOLTAGE * SumAdc(ADC_CHAN_LF, 32)) >> 15;
|
||||||
Dbprintf("LF 125/134kHz Baseline: %dmV", (MAX_ADC_LF_VOLTAGE * lf_av) >> 10);
|
Dbprintf("LF 125/134kHz Baseline: %dmV", lf_av);
|
||||||
lf_baseline = lf_av;
|
lf_baseline = lf_av;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -547,11 +574,11 @@ void ListenReaderField(uint8_t limit) {
|
||||||
|
|
||||||
#if defined RDV4
|
#if defined RDV4
|
||||||
// iceman, useless, since we are measuring readerfield, not our field. My tests shows a max of 20v from a reader.
|
// iceman, useless, since we are measuring readerfield, not our field. My tests shows a max of 20v from a reader.
|
||||||
hf_av = hf_max = AvgAdc(ADC_CHAN_HF_RDV40);
|
hf_av = hf_max = (MAX_ADC_HF_VOLTAGE_RDV40 * SumAdc(ADC_CHAN_HF_RDV40, 32)) >> 15;
|
||||||
#else
|
#else
|
||||||
hf_av = hf_max = AvgAdc(ADC_CHAN_HF);
|
hf_av = hf_max = (MAX_ADC_HF_VOLTAGE * SumAdc(ADC_CHAN_HF, 32)) >> 15;
|
||||||
#endif
|
#endif
|
||||||
Dbprintf("HF 13.56MHz Baseline: %dmV", (MAX_ADC_HF_VOLTAGE * hf_av) >> 10);
|
Dbprintf("HF 13.56MHz Baseline: %dmV", hf_av);
|
||||||
hf_baseline = hf_av;
|
hf_baseline = hf_av;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -583,10 +610,10 @@ void ListenReaderField(uint8_t limit) {
|
||||||
LED_D_OFF();
|
LED_D_OFF();
|
||||||
}
|
}
|
||||||
|
|
||||||
lf_av_new = AvgAdc(ADC_CHAN_LF);
|
lf_av_new = (MAX_ADC_LF_VOLTAGE * SumAdc(ADC_CHAN_LF, 32)) >> 15;
|
||||||
// see if there's a significant change
|
// see if there's a significant change
|
||||||
if (ABS(lf_av - lf_av_new) > REPORT_CHANGE) {
|
if (ABS(lf_av - lf_av_new) > REPORT_CHANGE) {
|
||||||
Dbprintf("LF 125/134kHz Field Change: %5dmV", (MAX_ADC_LF_VOLTAGE * lf_av_new) >> 10);
|
Dbprintf("LF 125/134kHz Field Change: %5dmV", lf_av_new);
|
||||||
lf_av = lf_av_new;
|
lf_av = lf_av_new;
|
||||||
if (lf_av > lf_max)
|
if (lf_av > lf_max)
|
||||||
lf_max = lf_av;
|
lf_max = lf_av;
|
||||||
|
@ -602,13 +629,13 @@ void ListenReaderField(uint8_t limit) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined RDV4
|
#if defined RDV4
|
||||||
hf_av_new = AvgAdc(ADC_CHAN_HF_RDV40);
|
hf_av_new = (MAX_ADC_HF_VOLTAGE_RDV40 * SumAdc(ADC_CHAN_HF_RDV40, 32)) >> 15;
|
||||||
#else
|
#else
|
||||||
hf_av_new = AvgAdc(ADC_CHAN_HF);
|
hf_av_new = (MAX_ADC_HF_VOLTAGE * SumAdc(ADC_CHAN_HF, 32)) >> 15;
|
||||||
#endif
|
#endif
|
||||||
// see if there's a significant change
|
// see if there's a significant change
|
||||||
if (ABS(hf_av - hf_av_new) > REPORT_CHANGE) {
|
if (ABS(hf_av - hf_av_new) > REPORT_CHANGE) {
|
||||||
Dbprintf("HF 13.56MHz Field Change: %5dmV", (MAX_ADC_HF_VOLTAGE * hf_av_new) >> 10);
|
Dbprintf("HF 13.56MHz Field Change: %5dmV", hf_av_new);
|
||||||
hf_av = hf_av_new;
|
hf_av = hf_av_new;
|
||||||
if (hf_av > hf_max)
|
if (hf_av > hf_max)
|
||||||
hf_max = hf_av;
|
hf_max = hf_av;
|
||||||
|
@ -701,8 +728,8 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||||
case CMD_BREAK_LOOP:
|
case CMD_BREAK_LOOP:
|
||||||
break;
|
break;
|
||||||
case CMD_QUIT_SESSION: {
|
case CMD_QUIT_SESSION: {
|
||||||
reply_via_fpc = false;
|
g_reply_via_fpc = false;
|
||||||
reply_via_usb = false;
|
g_reply_via_usb = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// emulator
|
// emulator
|
||||||
|
@ -763,9 +790,10 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||||
reply_mix(CMD_ACK, bits, 0, 0, 0, 0);
|
reply_mix(CMD_ACK, bits, 0, 0, 0, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CMD_LF_HID_DEMOD: {
|
case CMD_LF_HID_WATCH: {
|
||||||
uint32_t high, low;
|
uint32_t high, low;
|
||||||
CmdHIDdemodFSK(0, &high, &low, 1);
|
int res = lf_hid_watch(0, &high, &low);
|
||||||
|
reply_ng(CMD_LF_HID_WATCH, res, NULL, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CMD_LF_HID_SIMULATE: {
|
case CMD_LF_HID_SIMULATE: {
|
||||||
|
@ -797,19 +825,29 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||||
CopyHIDtoT55x7(packet->oldarg[0], packet->oldarg[1], packet->oldarg[2], packet->data.asBytes[0]);
|
CopyHIDtoT55x7(packet->oldarg[0], packet->oldarg[1], packet->oldarg[2], packet->data.asBytes[0]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CMD_LF_IO_DEMOD: {
|
case CMD_LF_IO_WATCH: {
|
||||||
uint32_t high, low;
|
uint32_t high, low;
|
||||||
CmdIOdemodFSK(0, &high, &low, 1);
|
int res = lf_io_watch(0, &high, &low);
|
||||||
|
reply_ng(CMD_LF_IO_WATCH, res, NULL, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CMD_LF_EM410X_DEMOD: {
|
case CMD_LF_EM410X_WATCH: {
|
||||||
uint32_t high;
|
uint32_t high;
|
||||||
uint64_t low;
|
uint64_t low;
|
||||||
CmdEM410xdemod(packet->oldarg[0], &high, &low, 1);
|
int res = lf_em410x_watch(0, &high, &low);
|
||||||
|
reply_ng(CMD_LF_EM410X_WATCH, res, NULL, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CMD_LF_EM410X_WRITE: {
|
case CMD_LF_EM410X_WRITE: {
|
||||||
WriteEM410x(packet->oldarg[0], packet->oldarg[1], packet->oldarg[2]);
|
struct p {
|
||||||
|
uint8_t card;
|
||||||
|
uint8_t clock;
|
||||||
|
uint32_t high;
|
||||||
|
uint32_t low;
|
||||||
|
} PACKED;
|
||||||
|
struct p *payload = (struct p *)packet->data.asBytes;
|
||||||
|
int res = copy_em410x_to_t55xx(payload->card, payload->clock, payload->high, payload->low);
|
||||||
|
reply_ng(CMD_LF_EM410X_WRITE, res, NULL, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CMD_LF_TI_READ: {
|
case CMD_LF_TI_READ: {
|
||||||
|
@ -911,10 +949,10 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||||
EM4xWriteWord(payload->address, payload->data, payload->password, payload->usepwd);
|
EM4xWriteWord(payload->address, payload->data, payload->password, payload->usepwd);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CMD_LF_AWID_DEMOD: {
|
case CMD_LF_AWID_WATCH: {
|
||||||
uint32_t high, low;
|
uint32_t high, low;
|
||||||
// Set realtime AWID demodulation
|
int res = lf_awid_watch(0, &high, &low);
|
||||||
CmdAWIDdemodFSK(0, &high, &low, 1);
|
reply_ng(CMD_LF_AWID_WATCH, res, NULL, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CMD_LF_VIKING_CLONE: {
|
case CMD_LF_VIKING_CLONE: {
|
||||||
|
@ -968,6 +1006,21 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef WITH_EM4x50
|
||||||
|
case CMD_LF_EM4X50_INFO: {
|
||||||
|
em4x50_info((em4x50_data_t *)packet->data.asBytes);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CMD_LF_EM4X50_WRITE: {
|
||||||
|
em4x50_write((em4x50_data_t *)packet->data.asBytes);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CMD_LF_EM4X50_WRITE_PASSWORD: {
|
||||||
|
em4x50_write_password((em4x50_data_t *)packet->data.asBytes);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef WITH_ISO15693
|
#ifdef WITH_ISO15693
|
||||||
case CMD_HF_ISO15693_ACQ_RAW_ADC: {
|
case CMD_HF_ISO15693_ACQ_RAW_ADC: {
|
||||||
AcquireRawAdcSamplesIso15693();
|
AcquireRawAdcSamplesIso15693();
|
||||||
|
@ -1395,7 +1448,20 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||||
|
|
||||||
#ifdef WITH_HFSNIFF
|
#ifdef WITH_HFSNIFF
|
||||||
case CMD_HF_SNIFF: {
|
case CMD_HF_SNIFF: {
|
||||||
HfSniff(packet->oldarg[0], packet->oldarg[1]);
|
struct p {
|
||||||
|
uint32_t samplesToSkip;
|
||||||
|
uint32_t triggersToSkip;
|
||||||
|
} PACKED;
|
||||||
|
struct p *payload = (struct p *)packet->data.asBytes;
|
||||||
|
|
||||||
|
uint16_t len = 0;
|
||||||
|
int res = HfSniff(payload->samplesToSkip, payload->triggersToSkip, &len);
|
||||||
|
|
||||||
|
struct {
|
||||||
|
uint16_t len;
|
||||||
|
} PACKED retval;
|
||||||
|
retval.len = len;
|
||||||
|
reply_ng(CMD_HF_SNIFF, res, (uint8_t *)&retval, sizeof(retval));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1654,12 +1720,12 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// offset should not be over buffer
|
// offset should not be over buffer
|
||||||
if (payload->offset >= BIGBUF_SIZE) {
|
if (payload->offset >= BigBuf_get_size()) {
|
||||||
reply_ng(CMD_LF_UPLOAD_SIM_SAMPLES, PM3_EOVFLOW, NULL, 0);
|
reply_ng(CMD_LF_UPLOAD_SIM_SAMPLES, PM3_EOVFLOW, NULL, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// ensure len bytes copied wont go past end of bigbuf
|
// ensure len bytes copied wont go past end of bigbuf
|
||||||
uint16_t len = MIN(BIGBUF_SIZE - payload->offset, sizeof(payload->data));
|
uint16_t len = MIN(BigBuf_get_size() - payload->offset, sizeof(payload->data));
|
||||||
|
|
||||||
uint8_t *mem = BigBuf_get_addr();
|
uint8_t *mem = BigBuf_get_addr();
|
||||||
|
|
||||||
|
@ -2049,7 +2115,11 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||||
void __attribute__((noreturn)) AppMain(void) {
|
void __attribute__((noreturn)) AppMain(void) {
|
||||||
|
|
||||||
SpinDelay(100);
|
SpinDelay(100);
|
||||||
clear_trace();
|
BigBuf_initialize();
|
||||||
|
|
||||||
|
for (uint32_t *p = &_stack_start; p < (uint32_t *)((uintptr_t)&_stack_end - 0x200); ++p) {
|
||||||
|
*p = 0xdeadbeef;
|
||||||
|
}
|
||||||
|
|
||||||
if (common_area.magic != COMMON_AREA_MAGIC || common_area.version != 1) {
|
if (common_area.magic != COMMON_AREA_MAGIC || common_area.version != 1) {
|
||||||
/* Initialize common area */
|
/* Initialize common area */
|
||||||
|
@ -2116,6 +2186,12 @@ void __attribute__((noreturn)) AppMain(void) {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
|
|
||||||
|
if (_stack_start != 0xdeadbeef) {
|
||||||
|
Dbprintf("Stack overflow detected! Please increase stack size, currently %d bytes", (&_stack_end - &_stack_start) << 2);
|
||||||
|
Dbprintf("Unplug your device now.");
|
||||||
|
while (1);
|
||||||
|
}
|
||||||
|
|
||||||
// Check if there is a packet available
|
// Check if there is a packet available
|
||||||
PacketCommandNG rx;
|
PacketCommandNG rx;
|
||||||
memset(&rx.data, 0, sizeof(rx.data));
|
memset(&rx.data, 0, sizeof(rx.data));
|
||||||
|
|
|
@ -13,9 +13,8 @@
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
extern int rsamples; // = 0;
|
extern int g_rsamples; // = 0;
|
||||||
extern uint8_t trigger;
|
extern uint8_t g_trigger;
|
||||||
extern bool allow_send_wtx;
|
|
||||||
|
|
||||||
// ADC Vref = 3300mV, and an (10M+1M):1M voltage divider on the HF input can measure voltages up to 36300 mV
|
// ADC Vref = 3300mV, and an (10M+1M):1M voltage divider on the HF input can measure voltages up to 36300 mV
|
||||||
#define MAX_ADC_HF_VOLTAGE 36300
|
#define MAX_ADC_HF_VOLTAGE 36300
|
||||||
|
@ -32,6 +31,7 @@ void ReadMem(int addr);
|
||||||
void __attribute__((noreturn)) AppMain(void);
|
void __attribute__((noreturn)) AppMain(void);
|
||||||
|
|
||||||
uint16_t AvgAdc(int ch);
|
uint16_t AvgAdc(int ch);
|
||||||
|
uint16_t SumAdc(int ch, int NbSamples);
|
||||||
|
|
||||||
//void PrintToSendBuffer(void);
|
//void PrintToSendBuffer(void);
|
||||||
void ToSendStuffBit(int b);
|
void ToSendStuffBit(int b);
|
||||||
|
@ -39,5 +39,6 @@ void ToSendReset(void);
|
||||||
void ListenReaderField(uint8_t limit);
|
void ListenReaderField(uint8_t limit);
|
||||||
void StandAloneMode(void);
|
void StandAloneMode(void);
|
||||||
void printStandAloneModes(void);
|
void printStandAloneModes(void);
|
||||||
|
void print_stack_usage(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
34
armsrc/cmd.c
34
armsrc/cmd.c
|
@ -36,11 +36,11 @@
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
|
|
||||||
// Flags to tell where to add CRC on sent replies
|
// Flags to tell where to add CRC on sent replies
|
||||||
bool reply_with_crc_on_usb = false;
|
bool g_reply_with_crc_on_usb = false;
|
||||||
bool reply_with_crc_on_fpc = true;
|
bool g_reply_with_crc_on_fpc = true;
|
||||||
// "Session" flag, to tell via which interface next msgs should be sent: USB or FPC USART
|
// "Session" flag, to tell via which interface next msgs should be sent: USB or FPC USART
|
||||||
bool reply_via_fpc = false;
|
bool g_reply_via_fpc = false;
|
||||||
bool reply_via_usb = false;
|
bool g_reply_via_usb = false;
|
||||||
|
|
||||||
int reply_old(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len) {
|
int reply_old(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len) {
|
||||||
PacketResponseOLD txcmd = {CMD_UNKNOWN, {0, 0, 0}, {{0}}};
|
PacketResponseOLD txcmd = {CMD_UNKNOWN, {0, 0, 0}, {{0}}};
|
||||||
|
@ -68,11 +68,11 @@ int reply_old(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *d
|
||||||
int resultusb = PM3_EUNDEF;
|
int resultusb = PM3_EUNDEF;
|
||||||
// Send frame and make sure all bytes are transmitted
|
// Send frame and make sure all bytes are transmitted
|
||||||
|
|
||||||
if (reply_via_usb) {
|
if (g_reply_via_usb) {
|
||||||
resultusb = usb_write((uint8_t *)&txcmd, sizeof(PacketResponseOLD));
|
resultusb = usb_write((uint8_t *)&txcmd, sizeof(PacketResponseOLD));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reply_via_fpc) {
|
if (g_reply_via_fpc) {
|
||||||
#ifdef WITH_FPC_USART_HOST
|
#ifdef WITH_FPC_USART_HOST
|
||||||
resultfpc = usart_writebuffer_sync((uint8_t *)&txcmd, sizeof(PacketResponseOLD));
|
resultfpc = usart_writebuffer_sync((uint8_t *)&txcmd, sizeof(PacketResponseOLD));
|
||||||
#else
|
#else
|
||||||
|
@ -80,9 +80,9 @@ int reply_old(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *d
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
// we got two results, let's prioritize the faulty one and USB over FPC.
|
// we got two results, let's prioritize the faulty one and USB over FPC.
|
||||||
if (reply_via_usb && (resultusb != PM3_SUCCESS)) return resultusb;
|
if (g_reply_via_usb && (resultusb != PM3_SUCCESS)) return resultusb;
|
||||||
#ifdef WITH_FPC_USART_HOST
|
#ifdef WITH_FPC_USART_HOST
|
||||||
if (reply_via_fpc && (resultfpc != PM3_SUCCESS)) return resultfpc;
|
if (g_reply_via_fpc && (resultfpc != PM3_SUCCESS)) return resultfpc;
|
||||||
#endif
|
#endif
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -112,7 +112,7 @@ static int reply_ng_internal(uint16_t cmd, int16_t status, uint8_t *data, size_t
|
||||||
|
|
||||||
PacketResponseNGPostamble *tx_post = (PacketResponseNGPostamble *)((uint8_t *)&txBufferNG + sizeof(PacketResponseNGPreamble) + len);
|
PacketResponseNGPostamble *tx_post = (PacketResponseNGPostamble *)((uint8_t *)&txBufferNG + sizeof(PacketResponseNGPreamble) + len);
|
||||||
// Note: if we send to both FPC & USB, we'll set CRC for both if any of them require CRC
|
// Note: if we send to both FPC & USB, we'll set CRC for both if any of them require CRC
|
||||||
if ((reply_via_fpc && reply_with_crc_on_fpc) || ((reply_via_usb) && reply_with_crc_on_usb)) {
|
if ((g_reply_via_fpc && g_reply_with_crc_on_fpc) || ((g_reply_via_usb) && g_reply_with_crc_on_usb)) {
|
||||||
uint8_t first, second;
|
uint8_t first, second;
|
||||||
compute_crc(CRC_14443_A, (uint8_t *)&txBufferNG, sizeof(PacketResponseNGPreamble) + len, &first, &second);
|
compute_crc(CRC_14443_A, (uint8_t *)&txBufferNG, sizeof(PacketResponseNGPreamble) + len, &first, &second);
|
||||||
tx_post->crc = (first << 8) + second;
|
tx_post->crc = (first << 8) + second;
|
||||||
|
@ -127,10 +127,10 @@ static int reply_ng_internal(uint16_t cmd, int16_t status, uint8_t *data, size_t
|
||||||
int resultusb = PM3_EUNDEF;
|
int resultusb = PM3_EUNDEF;
|
||||||
// Send frame and make sure all bytes are transmitted
|
// Send frame and make sure all bytes are transmitted
|
||||||
|
|
||||||
if (reply_via_usb) {
|
if (g_reply_via_usb) {
|
||||||
resultusb = usb_write((uint8_t *)&txBufferNG, txBufferNGLen);
|
resultusb = usb_write((uint8_t *)&txBufferNG, txBufferNGLen);
|
||||||
}
|
}
|
||||||
if (reply_via_fpc) {
|
if (g_reply_via_fpc) {
|
||||||
#ifdef WITH_FPC_USART_HOST
|
#ifdef WITH_FPC_USART_HOST
|
||||||
resultfpc = usart_writebuffer_sync((uint8_t *)&txBufferNG, txBufferNGLen);
|
resultfpc = usart_writebuffer_sync((uint8_t *)&txBufferNG, txBufferNGLen);
|
||||||
#else
|
#else
|
||||||
|
@ -138,9 +138,9 @@ static int reply_ng_internal(uint16_t cmd, int16_t status, uint8_t *data, size_t
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
// we got two results, let's prioritize the faulty one and USB over FPC.
|
// we got two results, let's prioritize the faulty one and USB over FPC.
|
||||||
if (reply_via_usb && (resultusb != PM3_SUCCESS)) return resultusb;
|
if (g_reply_via_usb && (resultusb != PM3_SUCCESS)) return resultusb;
|
||||||
#ifdef WITH_FPC_USART_HOST
|
#ifdef WITH_FPC_USART_HOST
|
||||||
if (reply_via_fpc && (resultfpc != PM3_SUCCESS)) return resultfpc;
|
if (g_reply_via_fpc && (resultfpc != PM3_SUCCESS)) return resultfpc;
|
||||||
#endif
|
#endif
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -216,8 +216,8 @@ static int receive_ng_internal(PacketCommandNG *rx, uint32_t read_ng(uint8_t *da
|
||||||
if ((first << 8) + second != rx->crc)
|
if ((first << 8) + second != rx->crc)
|
||||||
return PM3_EIO;
|
return PM3_EIO;
|
||||||
}
|
}
|
||||||
reply_via_usb = usb;
|
g_reply_via_usb = usb;
|
||||||
reply_via_fpc = fpc;
|
g_reply_via_fpc = fpc;
|
||||||
} else { // Old style command
|
} else { // Old style command
|
||||||
PacketCommandOLD rx_old;
|
PacketCommandOLD rx_old;
|
||||||
memcpy(&rx_old, &rx_raw.pre, sizeof(PacketCommandNGPreamble));
|
memcpy(&rx_old, &rx_raw.pre, sizeof(PacketCommandNGPreamble));
|
||||||
|
@ -225,8 +225,8 @@ static int receive_ng_internal(PacketCommandNG *rx, uint32_t read_ng(uint8_t *da
|
||||||
if (bytes != sizeof(PacketCommandOLD) - sizeof(PacketCommandNGPreamble))
|
if (bytes != sizeof(PacketCommandOLD) - sizeof(PacketCommandNGPreamble))
|
||||||
return PM3_EIO;
|
return PM3_EIO;
|
||||||
|
|
||||||
reply_via_usb = usb;
|
g_reply_via_usb = usb;
|
||||||
reply_via_fpc = fpc;
|
g_reply_via_fpc = fpc;
|
||||||
rx->ng = false;
|
rx->ng = false;
|
||||||
rx->magic = 0;
|
rx->magic = 0;
|
||||||
rx->crc = 0;
|
rx->crc = 0;
|
||||||
|
|
|
@ -37,11 +37,11 @@
|
||||||
#include "pm3_cmd.h"
|
#include "pm3_cmd.h"
|
||||||
|
|
||||||
// Flags to tell where to add CRC on sent replies
|
// Flags to tell where to add CRC on sent replies
|
||||||
extern bool reply_with_crc_on_usb;
|
extern bool g_reply_with_crc_on_usb;
|
||||||
extern bool reply_with_crc_on_fpc;
|
extern bool g_reply_with_crc_on_fpc;
|
||||||
// "Session" flag, to tell via which interface next msgs should be sent: USB and/or FPC USART
|
// "Session" flag, to tell via which interface next msgs should be sent: USB and/or FPC USART
|
||||||
extern bool reply_via_fpc;
|
extern bool g_reply_via_fpc;
|
||||||
extern bool reply_via_usb;
|
extern bool g_reply_via_usb;
|
||||||
|
|
||||||
int reply_old(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len);
|
int reply_old(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len);
|
||||||
int reply_ng(uint16_t cmd, int16_t status, uint8_t *data, size_t len);
|
int reply_ng(uint16_t cmd, int16_t status, uint8_t *data, size_t len);
|
||||||
|
|
|
@ -15,31 +15,31 @@
|
||||||
#include "ansi.h"
|
#include "ansi.h"
|
||||||
|
|
||||||
#define Dbprintf_usb(...) {\
|
#define Dbprintf_usb(...) {\
|
||||||
bool tmpfpc = reply_via_fpc;\
|
bool tmpfpc = g_reply_via_fpc;\
|
||||||
bool tmpusb = reply_via_usb;\
|
bool tmpusb = g_reply_via_usb;\
|
||||||
reply_via_fpc = false;\
|
g_reply_via_fpc = false;\
|
||||||
reply_via_usb = true;\
|
g_reply_via_usb = true;\
|
||||||
Dbprintf(__VA_ARGS__);\
|
Dbprintf(__VA_ARGS__);\
|
||||||
reply_via_fpc = tmpfpc;\
|
g_reply_via_fpc = tmpfpc;\
|
||||||
reply_via_usb = tmpusb;}
|
g_reply_via_usb = tmpusb;}
|
||||||
|
|
||||||
#define Dbprintf_fpc(...) {\
|
#define Dbprintf_fpc(...) {\
|
||||||
bool tmpfpc = reply_via_fpc;\
|
bool tmpfpc = g_reply_via_fpc;\
|
||||||
bool tmpusb = reply_via_usb;\
|
bool tmpusb = g_reply_via_usb;\
|
||||||
reply_via_fpc = true;\
|
g_reply_via_fpc = true;\
|
||||||
reply_via_usb = false;\
|
g_reply_via_usb = false;\
|
||||||
Dbprintf(__VA_ARGS__);\
|
Dbprintf(__VA_ARGS__);\
|
||||||
reply_via_fpc = tmpfpc;\
|
g_reply_via_fpc = tmpfpc;\
|
||||||
reply_via_usb = tmpusb;}
|
g_reply_via_usb = tmpusb;}
|
||||||
|
|
||||||
#define Dbprintf_all(...) {\
|
#define Dbprintf_all(...) {\
|
||||||
bool tmpfpc = reply_via_fpc;\
|
bool tmpfpc = g_reply_via_fpc;\
|
||||||
bool tmpusb = reply_via_usb;\
|
bool tmpusb = g_reply_via_usb;\
|
||||||
reply_via_fpc = true;\
|
g_reply_via_fpc = true;\
|
||||||
reply_via_usb = true;\
|
g_reply_via_usb = true;\
|
||||||
Dbprintf(__VA_ARGS__);\
|
Dbprintf(__VA_ARGS__);\
|
||||||
reply_via_fpc = tmpfpc;\
|
g_reply_via_fpc = tmpfpc;\
|
||||||
reply_via_usb = tmpusb;}
|
g_reply_via_usb = tmpusb;}
|
||||||
|
|
||||||
|
|
||||||
void DbpString(const char *str);
|
void DbpString(const char *str);
|
||||||
|
|
|
@ -46,9 +46,9 @@ static mbedtls_des_context ctx;
|
||||||
static mbedtls_des3_context ctx3;
|
static mbedtls_des3_context ctx3;
|
||||||
static mbedtls_aes_context actx;
|
static mbedtls_aes_context actx;
|
||||||
|
|
||||||
static inline void update_key_schedules(desfirekey_t key);
|
static void update_key_schedules(desfirekey_t key);
|
||||||
|
|
||||||
static inline void update_key_schedules(desfirekey_t key) {
|
static void update_key_schedules(desfirekey_t key) {
|
||||||
// DES_set_key ((DES_cblock *)key->data, &(key->ks1));
|
// DES_set_key ((DES_cblock *)key->data, &(key->ks1));
|
||||||
// DES_set_key ((DES_cblock *)(key->data + 8), &(key->ks2));
|
// DES_set_key ((DES_cblock *)(key->data + 8), &(key->ks2));
|
||||||
// if (T_3K3DES == key->type) {
|
// if (T_3K3DES == key->type) {
|
||||||
|
|
911
armsrc/em4x50.c
Normal file
911
armsrc/em4x50.c
Normal file
|
@ -0,0 +1,911 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Copyright (C) 2020 tharexde
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Low frequency EM4x50 commands
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include "fpgaloader.h"
|
||||||
|
#include "ticks.h"
|
||||||
|
#include "dbprint.h"
|
||||||
|
#include "lfadc.h"
|
||||||
|
#include "commonutil.h"
|
||||||
|
#include "em4x50.h"
|
||||||
|
|
||||||
|
// 4 data bytes
|
||||||
|
// + byte with row parities
|
||||||
|
// + column parity byte
|
||||||
|
// + byte with stop bit
|
||||||
|
|
||||||
|
static em4x50_tag_t tag = {
|
||||||
|
.sectors = {
|
||||||
|
[0] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // password
|
||||||
|
[1] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // protection word
|
||||||
|
[2] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // control word
|
||||||
|
[3] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||||
|
[4] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||||
|
[5] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||||
|
[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||||
|
[7] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||||
|
[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||||
|
[9] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||||
|
[10] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||||
|
[11] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||||
|
[12] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||||
|
[13] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||||
|
[14] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||||
|
[15] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||||
|
[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||||
|
[17] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||||
|
[18] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||||
|
[19] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||||
|
[20] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||||
|
[21] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||||
|
[22] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||||
|
[23] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||||
|
[24] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||||
|
[25] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||||
|
[26] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||||
|
[27] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||||
|
[28] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||||
|
[29] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||||
|
[30] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||||
|
[31] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||||
|
[32] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // device serial number
|
||||||
|
[33] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // device identification
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Sam7s has several timers, we will use the source TIMER_CLOCK1 (aka AT91C_TC_CLKS_TIMER_DIV1_CLOCK)
|
||||||
|
// TIMER_CLOCK1 = MCK/2, MCK is running at 48 MHz, Timer is running at 48/2 = 24 MHz
|
||||||
|
// EM4x50 units (T0) have duration of 8 microseconds (us), which is 1/125000 per second (carrier)
|
||||||
|
// T0 = TIMER_CLOCK1 / 125000 = 192
|
||||||
|
|
||||||
|
#ifndef T0
|
||||||
|
#define T0 192
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define EM4X50_T_TAG_QUARTER_PERIOD 16
|
||||||
|
#define EM4X50_T_TAG_HALF_PERIOD 32
|
||||||
|
#define EM4X50_T_TAG_THREE_QUARTER_PERIOD 48
|
||||||
|
#define EM4X50_T_TAG_FULL_PERIOD 64
|
||||||
|
#define EM4X50_T_WAITING_FOR_LIW 500
|
||||||
|
#define EM4X50_T_TAG_TPP 64
|
||||||
|
#define EM4X50_T_TAG_TWA 64
|
||||||
|
|
||||||
|
#define EM4X50_TAG_TOLERANCE 8
|
||||||
|
#define EM4X50_TAG_WORD 45
|
||||||
|
|
||||||
|
#define EM4X50_BIT_0 0
|
||||||
|
#define EM4X50_BIT_1 1
|
||||||
|
#define EM4X50_BIT_OTHER 2
|
||||||
|
|
||||||
|
#define EM4X50_COMMAND_LOGIN 0x01
|
||||||
|
#define EM4X50_COMMAND_RESET 0x80
|
||||||
|
#define EM4X50_COMMAND_WRITE 0x12
|
||||||
|
#define EM4X50_COMMAND_WRITE_PASSWORD 0x11
|
||||||
|
#define EM4X50_COMMAND_SELECTIVE_READ 0x0A
|
||||||
|
|
||||||
|
#define FPGA_TIMER_0 0
|
||||||
|
|
||||||
|
int gHigh = 0;
|
||||||
|
int gLow = 0;
|
||||||
|
|
||||||
|
// auxiliary functions
|
||||||
|
|
||||||
|
static void init_tag(void) {
|
||||||
|
|
||||||
|
// initialize global tag structure
|
||||||
|
|
||||||
|
for (int i = 0; i < 34; i++)
|
||||||
|
for (int j = 0; j < 7; j++)
|
||||||
|
tag.sectors[i][j] = 0x00;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t bits2byte(uint8_t *bits, int length) {
|
||||||
|
|
||||||
|
// converts <length> separate bits into a single "byte"
|
||||||
|
|
||||||
|
uint8_t byte = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
|
||||||
|
byte |= bits[i];
|
||||||
|
|
||||||
|
if (i != length-1)
|
||||||
|
byte <<= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return byte;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void msb2lsb_word(uint8_t *word) {
|
||||||
|
|
||||||
|
// reorders given <word> according to EM4x50 datasheet (msb -> lsb)
|
||||||
|
|
||||||
|
uint8_t buff[4];
|
||||||
|
|
||||||
|
buff[0] = reflect8(word[3]);
|
||||||
|
buff[1] = reflect8(word[2]);
|
||||||
|
buff[2] = reflect8(word[1]);
|
||||||
|
buff[3] = reflect8(word[0]);
|
||||||
|
|
||||||
|
word[0] = buff[0];
|
||||||
|
word[1] = buff[1];
|
||||||
|
word[2] = buff[2];
|
||||||
|
word[3] = buff[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void save_word(int pos, uint8_t bits[EM4X50_TAG_WORD]) {
|
||||||
|
|
||||||
|
// split "raw" word into data, row and column parity bits and stop bit and
|
||||||
|
// save them in global tag structure
|
||||||
|
|
||||||
|
uint8_t row_parity[4];
|
||||||
|
uint8_t col_parity[8];
|
||||||
|
|
||||||
|
// data and row parities
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
tag.sectors[pos][i] = bits2byte(&bits[9*i],8);
|
||||||
|
row_parity[i] = bits[9*i+8];
|
||||||
|
}
|
||||||
|
|
||||||
|
tag.sectors[pos][4] = bits2byte(row_parity,4);
|
||||||
|
|
||||||
|
// column parities
|
||||||
|
for (int i = 0; i < 8; i++)
|
||||||
|
col_parity[i] = bits[36+i];
|
||||||
|
|
||||||
|
tag.sectors[pos][5] = bits2byte(col_parity,8);
|
||||||
|
|
||||||
|
// stop bit
|
||||||
|
tag.sectors[pos][6] = bits[44];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wait_timer(int timer, uint32_t period) {
|
||||||
|
|
||||||
|
// do nothing for <period> using timer <timer>
|
||||||
|
|
||||||
|
if (timer == FPGA_TIMER_0) {
|
||||||
|
|
||||||
|
AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG;
|
||||||
|
while (AT91C_BASE_TC0->TC_CV < period);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
AT91C_BASE_TC1->TC_CCR = AT91C_TC_SWTRG;
|
||||||
|
while (AT91C_BASE_TC1->TC_CV < period);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void em4x50_setup_read(void) {
|
||||||
|
|
||||||
|
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||||
|
|
||||||
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
|
||||||
|
|
||||||
|
// 50ms for the resonant antenna to settle.
|
||||||
|
SpinDelay(50);
|
||||||
|
// Now set up the SSC to get the ADC samples that are now streaming at us.
|
||||||
|
FpgaSetupSsc();
|
||||||
|
// start a 1.5ticks is 1us
|
||||||
|
StartTicks();
|
||||||
|
|
||||||
|
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_125);
|
||||||
|
|
||||||
|
// Connect the A/D to the peak-detected low-frequency path.
|
||||||
|
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
|
||||||
|
|
||||||
|
// Steal this pin from the SSP (SPI communication channel with fpga) and
|
||||||
|
// use it to control the modulation
|
||||||
|
AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT;
|
||||||
|
AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT;
|
||||||
|
|
||||||
|
// Disable modulation at default, which means enable the field
|
||||||
|
LOW(GPIO_SSC_DOUT);
|
||||||
|
|
||||||
|
// Enable Peripheral Clock for
|
||||||
|
// TIMER_CLOCK0, used to measure exact timing before answering
|
||||||
|
// TIMER_CLOCK1, used to capture edges of the tag frames
|
||||||
|
AT91C_BASE_PMC->PMC_PCER |= (1 << AT91C_ID_TC0) | (1 << AT91C_ID_TC1);
|
||||||
|
AT91C_BASE_PIOA->PIO_BSR = GPIO_SSC_FRAME;
|
||||||
|
|
||||||
|
// Disable timer during configuration
|
||||||
|
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;
|
||||||
|
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
|
||||||
|
|
||||||
|
// TC0: Capture mode, default timer source = MCK/2 (TIMER_CLOCK1), no triggers
|
||||||
|
AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK;
|
||||||
|
|
||||||
|
// TC1: Capture mode, default timer source = MCK/2 (TIMER_CLOCK1), no triggers
|
||||||
|
AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK;
|
||||||
|
|
||||||
|
// Enable and reset counters
|
||||||
|
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
|
||||||
|
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
|
||||||
|
|
||||||
|
// synchronized startup procedure
|
||||||
|
while (AT91C_BASE_TC0->TC_CV > 0) {}; // wait until TC1 returned to zero
|
||||||
|
|
||||||
|
// Watchdog hit
|
||||||
|
WDT_HIT();
|
||||||
|
}
|
||||||
|
|
||||||
|
// functions for "reader" use case
|
||||||
|
|
||||||
|
static void get_signalproperties(void) {
|
||||||
|
|
||||||
|
// calculate signal properties (mean amplitudes) from measured data:
|
||||||
|
// 32 amplitudes (maximum values) -> mean amplitude value -> gHigh -> gLow
|
||||||
|
|
||||||
|
int no_periods = 32, pct = 75, noise = 140;
|
||||||
|
uint8_t sample = 0, sample_ref = 127;
|
||||||
|
uint8_t sample_max_mean = 0;
|
||||||
|
uint8_t sample_max[no_periods];
|
||||||
|
uint32_t sample_max_sum = 0;
|
||||||
|
|
||||||
|
// wait until signal/noise > 1
|
||||||
|
while (AT91C_BASE_SSC->SSC_RHR < noise);
|
||||||
|
|
||||||
|
// calculate mean maximum value of 32 periods, each period has a length of
|
||||||
|
// 3 single "full periods" to eliminate the influence of a listen window
|
||||||
|
for (int i = 0; i < no_periods; i++) {
|
||||||
|
|
||||||
|
AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG;
|
||||||
|
while (AT91C_BASE_TC0->TC_CV < T0 * 3 * EM4X50_T_TAG_FULL_PERIOD) {
|
||||||
|
|
||||||
|
sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||||
|
|
||||||
|
if (sample > sample_max[i])
|
||||||
|
sample_max[i] = sample;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
sample_max_sum += sample_max[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
sample_max_mean = sample_max_sum / no_periods;
|
||||||
|
|
||||||
|
// set global envelope variables
|
||||||
|
gHigh = sample_ref + pct * (sample_max_mean - sample_ref) / 100;
|
||||||
|
gLow = sample_ref - pct * (sample_max_mean - sample_ref) / 100;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_next_bit(void) {
|
||||||
|
|
||||||
|
// returns bit value (or EM4X50_BIT_OTHER -> no bit pattern) by evaluating
|
||||||
|
// a single sample within a bit period (given there is no LIW, ACK or NAK)
|
||||||
|
// This function is not used for decoding, it is only used for identifying
|
||||||
|
// a listen window (return value = EM4X50_BIT_OTHER) in functions
|
||||||
|
// "find_double_listen_window" and "check_ack"
|
||||||
|
|
||||||
|
uint8_t sample;
|
||||||
|
|
||||||
|
// get sample at 3/4 of bit period
|
||||||
|
wait_timer(0, T0 * EM4X50_T_TAG_THREE_QUARTER_PERIOD);
|
||||||
|
sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||||
|
|
||||||
|
// wait until end of bit period
|
||||||
|
wait_timer(0, T0 * EM4X50_T_TAG_QUARTER_PERIOD);
|
||||||
|
|
||||||
|
// decide wether "0" or "1"
|
||||||
|
if (sample > gHigh)
|
||||||
|
return EM4X50_BIT_0;
|
||||||
|
else if (sample < gLow)
|
||||||
|
return EM4X50_BIT_1;
|
||||||
|
|
||||||
|
return EM4X50_BIT_OTHER;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t get_pulse_length(void) {
|
||||||
|
|
||||||
|
// iterates pulse length (low -> high -> low)
|
||||||
|
|
||||||
|
uint8_t sample = 0;
|
||||||
|
|
||||||
|
sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||||
|
|
||||||
|
while (sample > gLow)
|
||||||
|
sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||||
|
|
||||||
|
AT91C_BASE_TC1->TC_CCR = AT91C_TC_SWTRG;
|
||||||
|
|
||||||
|
while (sample < gHigh)
|
||||||
|
sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||||
|
|
||||||
|
while (sample > gLow)
|
||||||
|
sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||||
|
|
||||||
|
return (uint32_t)AT91C_BASE_TC1->TC_CV;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool check_pulse_length(uint32_t pl, int length) {
|
||||||
|
|
||||||
|
// check if pulse length <pl> corresponds to given length <length>
|
||||||
|
|
||||||
|
if ((pl >= T0 * (length - EM4X50_TAG_TOLERANCE)) &
|
||||||
|
(pl <= T0 * (length + EM4X50_TAG_TOLERANCE)))
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void em4x50_send_bit(int bit) {
|
||||||
|
|
||||||
|
// send single bit according to EM4x50 application note and datasheet
|
||||||
|
|
||||||
|
// reset clock for the next bit
|
||||||
|
AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG;
|
||||||
|
|
||||||
|
if (bit == 0) {
|
||||||
|
|
||||||
|
// disable modulation (drop the field) for 7 cycles of carrier
|
||||||
|
// period (Opt64)
|
||||||
|
LOW(GPIO_SSC_DOUT);
|
||||||
|
while (AT91C_BASE_TC0->TC_CV < T0 * 7);
|
||||||
|
|
||||||
|
// enable modulation (activates the field) for remaining first
|
||||||
|
// half of bit period
|
||||||
|
HIGH(GPIO_SSC_DOUT);
|
||||||
|
while (AT91C_BASE_TC0->TC_CV < T0 * EM4X50_T_TAG_HALF_PERIOD);
|
||||||
|
|
||||||
|
// disable modulation for second half of bit period
|
||||||
|
LOW(GPIO_SSC_DOUT);
|
||||||
|
while (AT91C_BASE_TC0->TC_CV < T0 * EM4X50_T_TAG_FULL_PERIOD);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// bit = "1" means disable modulation for full bit period
|
||||||
|
LOW(GPIO_SSC_DOUT);
|
||||||
|
while (AT91C_BASE_TC0->TC_CV < T0 * EM4X50_T_TAG_FULL_PERIOD);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void em4x50_send_byte(uint8_t byte) {
|
||||||
|
|
||||||
|
// send byte (without parity)
|
||||||
|
|
||||||
|
for (int i = 0; i < 8; i++)
|
||||||
|
em4x50_send_bit((byte >> (7-i)) & 1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void em4x50_send_byte_with_parity(uint8_t byte) {
|
||||||
|
|
||||||
|
// send byte followed by its (equal) parity bit
|
||||||
|
|
||||||
|
int parity = 0, bit = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
bit = (byte >> (7-i)) & 1;
|
||||||
|
em4x50_send_bit(bit);
|
||||||
|
parity ^= bit;
|
||||||
|
}
|
||||||
|
|
||||||
|
em4x50_send_bit(parity);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void em4x50_send_word(const uint8_t bytes[4]) {
|
||||||
|
|
||||||
|
// send 32 bit word with parity bits according to EM4x50 datasheet
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
em4x50_send_byte_with_parity(bytes[i]);
|
||||||
|
|
||||||
|
// send column parities
|
||||||
|
em4x50_send_byte(bytes[0] ^ bytes[1] ^ bytes[2] ^ bytes[3]);
|
||||||
|
|
||||||
|
// send final stop bit (always "0")
|
||||||
|
em4x50_send_bit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool find_double_listen_window(bool bcommand) {
|
||||||
|
|
||||||
|
// find two successive listen windows that indicate the beginning of
|
||||||
|
// data transmission
|
||||||
|
|
||||||
|
AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG;
|
||||||
|
while (AT91C_BASE_TC0->TC_CV < T0 * EM4X50_T_WAITING_FOR_LIW) {
|
||||||
|
|
||||||
|
// identification of listen window is done via evaluation of
|
||||||
|
// pulse lengths
|
||||||
|
if (check_pulse_length(get_pulse_length(), 3 * EM4X50_T_TAG_FULL_PERIOD)) {
|
||||||
|
|
||||||
|
if (check_pulse_length(get_pulse_length(), 2 * EM4X50_T_TAG_FULL_PERIOD)) {
|
||||||
|
|
||||||
|
// first listen window found
|
||||||
|
|
||||||
|
if (bcommand) {
|
||||||
|
|
||||||
|
// data transmission from card has to be stopped, because
|
||||||
|
// a commamd shall be issued
|
||||||
|
|
||||||
|
// unfortunately the posititon 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
|
||||||
|
|
||||||
|
// skip the next bit...
|
||||||
|
wait_timer(FPGA_TIMER_0, T0 * EM4X50_T_TAG_FULL_PERIOD);
|
||||||
|
|
||||||
|
// ...and check if the following bit does make sense
|
||||||
|
// (if not it is the correct position within the second
|
||||||
|
// listen window)
|
||||||
|
if (get_next_bit() == EM4X50_BIT_OTHER) {
|
||||||
|
|
||||||
|
// send RM for request mode
|
||||||
|
em4x50_send_bit(0);
|
||||||
|
em4x50_send_bit(0);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check_pulse_length(get_pulse_length(), 3 * EM4X50_T_TAG_FULL_PERIOD)) {
|
||||||
|
|
||||||
|
// return although second listen window consists of one
|
||||||
|
// more bit period but this period is necessary for
|
||||||
|
// evaluating further pulse lengths
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
// possible when using pulse lengths a double listen window is used.
|
||||||
|
|
||||||
|
bool bcommand = true;
|
||||||
|
|
||||||
|
return find_double_listen_window(bcommand);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool check_ack(bool bliw) {
|
||||||
|
|
||||||
|
// returns true if signal structue corresponds to ACK, anything else is
|
||||||
|
// counted as NAK (-> false)
|
||||||
|
// Only relevant for pasword writing function:
|
||||||
|
// If <bliw> is true then within the single listen window right after the
|
||||||
|
// ack signal a RM request has to be sent.
|
||||||
|
|
||||||
|
AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG;
|
||||||
|
while (AT91C_BASE_TC0->TC_CV < T0 * 4 * EM4X50_T_TAG_FULL_PERIOD) {
|
||||||
|
|
||||||
|
if (check_pulse_length(get_pulse_length(), 2 * EM4X50_T_TAG_FULL_PERIOD)) {
|
||||||
|
|
||||||
|
// The received signal is either ACK or NAK.
|
||||||
|
|
||||||
|
if (check_pulse_length(get_pulse_length(), 2 * EM4X50_T_TAG_FULL_PERIOD)) {
|
||||||
|
|
||||||
|
// Now the signal must be ACK.
|
||||||
|
|
||||||
|
if (!bliw) {
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// send RM request after ack signal
|
||||||
|
|
||||||
|
// wait for 2 bits (remaining "bit" of ACK signal + first
|
||||||
|
// "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
|
||||||
|
// as a valid bit it must belong to a listen window)
|
||||||
|
if (get_next_bit() == EM4X50_BIT_OTHER) {
|
||||||
|
|
||||||
|
// send RM for request mode
|
||||||
|
em4x50_send_bit(0);
|
||||||
|
em4x50_send_bit(0);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_word_from_bitstream(uint8_t bits[EM4X50_TAG_WORD]) {
|
||||||
|
|
||||||
|
// decodes one word by evaluating pulse lengths and previous bit;
|
||||||
|
// word must have 45 bits in total:
|
||||||
|
// 32 data bits + 4 row parity bits + 8 column parity bits + 1 stop bit
|
||||||
|
|
||||||
|
bool bbitchange = false;
|
||||||
|
int i = 0;
|
||||||
|
uint32_t pl = 0;
|
||||||
|
|
||||||
|
// initial bit value depends on last pulse length of listen window
|
||||||
|
pl = get_pulse_length();
|
||||||
|
if (check_pulse_length(pl, 3 * EM4X50_T_TAG_HALF_PERIOD)) {
|
||||||
|
|
||||||
|
// pulse length = 1.5
|
||||||
|
bits[0] = 1;
|
||||||
|
|
||||||
|
} else if (check_pulse_length(pl, 2 * EM4X50_T_TAG_FULL_PERIOD)) {
|
||||||
|
|
||||||
|
// pulse length = 2
|
||||||
|
bits[0] = 0;
|
||||||
|
bbitchange = true;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// pulse length = 2.5
|
||||||
|
bits[0] = 0;
|
||||||
|
bits[1] = 1;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// identify remaining bits based on pulse lengths
|
||||||
|
// between two listen windows only pulse lengths of 1, 1.5 and 2 are possible
|
||||||
|
while (true) {
|
||||||
|
|
||||||
|
i++;
|
||||||
|
pl = get_pulse_length();
|
||||||
|
|
||||||
|
if (check_pulse_length(pl, EM4X50_T_TAG_FULL_PERIOD)) {
|
||||||
|
|
||||||
|
// pulse length = 1 -> keep former bit value
|
||||||
|
bits[i] = bits[i-1];
|
||||||
|
|
||||||
|
} else if (check_pulse_length(pl, 3 * EM4X50_T_TAG_HALF_PERIOD)) {
|
||||||
|
|
||||||
|
// pulse length = 1.5 -> decision on bit change
|
||||||
|
|
||||||
|
if (bbitchange) {
|
||||||
|
|
||||||
|
// if number of pulse lengths with 1.5 periods is even -> add bit
|
||||||
|
bits[i] = (bits[i-1] == 1) ? 1 : 0;
|
||||||
|
|
||||||
|
// pulse length of 1.5 changes bit value
|
||||||
|
bits[i+1] = (bits[i] == 1) ? 0 : 1;
|
||||||
|
i++;
|
||||||
|
|
||||||
|
// next time add only one bit
|
||||||
|
bbitchange = false;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
bits[i] = (bits[i-1] == 1) ? 0 : 1;
|
||||||
|
|
||||||
|
// next time two bits have to be added
|
||||||
|
bbitchange = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (check_pulse_length(pl, 2 * EM4X50_T_TAG_FULL_PERIOD)) {
|
||||||
|
|
||||||
|
// pulse length of 2 means: adding 2 bits "01"
|
||||||
|
bits[i] = 0;
|
||||||
|
bits[i+1] = 1;
|
||||||
|
i++;
|
||||||
|
|
||||||
|
} else if (check_pulse_length(pl, 3 * EM4X50_T_TAG_FULL_PERIOD)) {
|
||||||
|
|
||||||
|
// pulse length of 3 indicates listen window -> clear last
|
||||||
|
// bit (= 0) and return
|
||||||
|
return --i;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// login function
|
||||||
|
|
||||||
|
static bool login(uint8_t password[4]) {
|
||||||
|
|
||||||
|
// simple login to EM4x50,
|
||||||
|
// used in operations that require authentication
|
||||||
|
|
||||||
|
if (request_receive_mode ()) {
|
||||||
|
|
||||||
|
// send login command
|
||||||
|
em4x50_send_byte_with_parity(EM4X50_COMMAND_LOGIN);
|
||||||
|
|
||||||
|
// send password
|
||||||
|
em4x50_send_word(password);
|
||||||
|
|
||||||
|
// check if ACK is returned
|
||||||
|
if (check_ack(false))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (DBGLEVEL >= DBG_ERROR)
|
||||||
|
Dbprintf("error in command request");
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// reset function
|
||||||
|
|
||||||
|
static bool reset(void) {
|
||||||
|
|
||||||
|
// resets EM4x50 tag (used by write function)
|
||||||
|
|
||||||
|
if (request_receive_mode ()) {
|
||||||
|
|
||||||
|
// send login command
|
||||||
|
em4x50_send_byte_with_parity(EM4X50_COMMAND_RESET);
|
||||||
|
|
||||||
|
if (check_ack(false))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (DBGLEVEL >= DBG_ERROR)
|
||||||
|
Dbprintf("error in command request");
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// read functions
|
||||||
|
|
||||||
|
static bool standard_read(int *now) {
|
||||||
|
|
||||||
|
// reads data that tag transmits when exposed to reader field
|
||||||
|
// (standard read mode); number of read words is saved in <now>
|
||||||
|
|
||||||
|
int fwr = *now;
|
||||||
|
uint8_t bits[EM4X50_TAG_WORD] = {0};
|
||||||
|
|
||||||
|
// start with the identification of two succsessive listening windows
|
||||||
|
if (find_double_listen_window(false)) {
|
||||||
|
|
||||||
|
// read and save words until following double listen window is detected
|
||||||
|
while (get_word_from_bitstream(bits) == EM4X50_TAG_WORD)
|
||||||
|
save_word((*now)++, bits);
|
||||||
|
|
||||||
|
// number of detected words
|
||||||
|
*now -= fwr;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (DBGLEVEL >= DBG_ERROR)
|
||||||
|
Dbprintf("didn't find a listen window");
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool selective_read(uint8_t addresses[4]) {
|
||||||
|
|
||||||
|
// reads from "first word read" (fwr = addresses[3]) to "last word read"
|
||||||
|
// (lwr = addresses[2])
|
||||||
|
// result is verified by "standard read mode"
|
||||||
|
|
||||||
|
int fwr = addresses[3]; // first word read
|
||||||
|
int lwr = addresses[2]; // last word read
|
||||||
|
int now = fwr; // number of words
|
||||||
|
|
||||||
|
if (request_receive_mode()) {
|
||||||
|
|
||||||
|
// send selective read command
|
||||||
|
em4x50_send_byte_with_parity(EM4X50_COMMAND_SELECTIVE_READ);
|
||||||
|
|
||||||
|
// send address data
|
||||||
|
em4x50_send_word(addresses);
|
||||||
|
|
||||||
|
// look for ACK sequence
|
||||||
|
if (check_ack(false))
|
||||||
|
|
||||||
|
// save and verify via standard read mode (compare number of words)
|
||||||
|
if (standard_read(&now))
|
||||||
|
if (now == (lwr - fwr + 1))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (DBGLEVEL >= DBG_ERROR)
|
||||||
|
Dbprintf("error in command request");
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void em4x50_info(em4x50_data_t *etd) {
|
||||||
|
|
||||||
|
// collects as much information as possible via selective read mode
|
||||||
|
// if no password is given -> try with standard password "0x00000000"
|
||||||
|
// otherwise continue without login
|
||||||
|
|
||||||
|
bool bsuccess = false, blogin = false;
|
||||||
|
uint8_t status = 0;
|
||||||
|
uint8_t addresses[] = {0x00, 0x00, 0x21, 0x00}; // fwr = 0, lwr = 33
|
||||||
|
uint8_t password[] = {0x00, 0x00, 0x00, 0x00}; // default password
|
||||||
|
|
||||||
|
init_tag();
|
||||||
|
em4x50_setup_read();
|
||||||
|
|
||||||
|
// set gHigh and gLow
|
||||||
|
get_signalproperties();
|
||||||
|
|
||||||
|
if (etd->pwd_given) {
|
||||||
|
|
||||||
|
// try to login with given password
|
||||||
|
blogin = login(etd->password);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// if no password is given, try to login with "0x00000000"
|
||||||
|
blogin = login(password);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bsuccess = selective_read(addresses);
|
||||||
|
|
||||||
|
status = (bsuccess << 1) + blogin;
|
||||||
|
|
||||||
|
lf_finalize();
|
||||||
|
reply_ng(CMD_ACK, status, (uint8_t *)tag.sectors, 238);
|
||||||
|
}
|
||||||
|
|
||||||
|
// write functions
|
||||||
|
|
||||||
|
static bool write(uint8_t word[4], uint8_t address) {
|
||||||
|
|
||||||
|
// writes <word> to specified <address>
|
||||||
|
|
||||||
|
if (request_receive_mode()) {
|
||||||
|
|
||||||
|
// send write command
|
||||||
|
em4x50_send_byte_with_parity(EM4X50_COMMAND_WRITE);
|
||||||
|
|
||||||
|
// send address data
|
||||||
|
em4x50_send_byte_with_parity(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);
|
||||||
|
|
||||||
|
// 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 true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (DBGLEVEL >= DBG_ERROR)
|
||||||
|
Dbprintf("error in command request");
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool write_password(uint8_t password[4], uint8_t new_password[4]) {
|
||||||
|
|
||||||
|
// changes password from <password> to <new_password>
|
||||||
|
|
||||||
|
if (request_receive_mode()) {
|
||||||
|
|
||||||
|
// send write password command
|
||||||
|
em4x50_send_byte_with_parity(EM4X50_COMMAND_WRITE_PASSWORD);
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
// look for ACK sequence and send rm request
|
||||||
|
// during following listen window
|
||||||
|
if (check_ack(true)) {
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (DBGLEVEL >= DBG_ERROR)
|
||||||
|
Dbprintf("error in command request");
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void em4x50_write(em4x50_data_t *etd) {
|
||||||
|
|
||||||
|
// write operation process for EM4x50 tag,
|
||||||
|
// single word is written to given address, verified by selective read operation
|
||||||
|
|
||||||
|
bool bsuccess = false, blogin = false;
|
||||||
|
uint8_t status = 0;
|
||||||
|
uint8_t word[4] = {0x00, 0x00, 0x00, 0x00};
|
||||||
|
uint8_t addresses[4] = {0x00, 0x00, 0x00, 0x00};
|
||||||
|
|
||||||
|
init_tag();
|
||||||
|
em4x50_setup_read();
|
||||||
|
|
||||||
|
// set gHigh and gLow
|
||||||
|
get_signalproperties();
|
||||||
|
|
||||||
|
// reorder word according to datasheet
|
||||||
|
msb2lsb_word(etd->word);
|
||||||
|
|
||||||
|
// if password is given try to login first
|
||||||
|
if (etd->pwd_given)
|
||||||
|
blogin = login(etd->password);
|
||||||
|
|
||||||
|
// write word to given address
|
||||||
|
if (write(etd->word, etd->address)) {
|
||||||
|
|
||||||
|
// to verify result reset EM4x50
|
||||||
|
if (reset()) {
|
||||||
|
|
||||||
|
// if password is given login
|
||||||
|
if (etd->pwd_given)
|
||||||
|
blogin &= login(etd->password);
|
||||||
|
|
||||||
|
// perform a selective read
|
||||||
|
addresses[2] = addresses[3] = etd->address;
|
||||||
|
if (selective_read(addresses)) {
|
||||||
|
|
||||||
|
// compare with given word
|
||||||
|
word[0] = tag.sectors[etd->address][0];
|
||||||
|
word[1] = tag.sectors[etd->address][1];
|
||||||
|
word[2] = tag.sectors[etd->address][2];
|
||||||
|
word[3] = tag.sectors[etd->address][3];
|
||||||
|
msb2lsb_word(word);
|
||||||
|
|
||||||
|
bsuccess = true;
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
bsuccess &= (word[i] == etd->word[i]) ? true : false;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
status = (bsuccess << 1) + blogin;
|
||||||
|
|
||||||
|
lf_finalize();
|
||||||
|
reply_ng(CMD_ACK, status, (uint8_t *)tag.sectors, 238);
|
||||||
|
}
|
||||||
|
|
||||||
|
void em4x50_write_password(em4x50_data_t *etd) {
|
||||||
|
|
||||||
|
// sinmple change of password
|
||||||
|
|
||||||
|
bool bsuccess = false;
|
||||||
|
|
||||||
|
init_tag();
|
||||||
|
em4x50_setup_read();
|
||||||
|
|
||||||
|
// set gHigh and gLow
|
||||||
|
get_signalproperties();
|
||||||
|
|
||||||
|
// login and change password
|
||||||
|
if (login(etd->password)) {
|
||||||
|
bsuccess = write_password(etd->password, etd->new_password);
|
||||||
|
}
|
||||||
|
|
||||||
|
lf_finalize();
|
||||||
|
reply_ng(CMD_ACK, bsuccess, 0, 0);
|
||||||
|
}
|
24
armsrc/em4x50.h
Normal file
24
armsrc/em4x50.h
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Copyright (C) 2020 tharexde
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Low frequency EM4x50 commands
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef EM4X50_H
|
||||||
|
#define EM4X50_H
|
||||||
|
|
||||||
|
#include "../include/em4x50.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t sectors[34][7];
|
||||||
|
} em4x50_tag_t;
|
||||||
|
|
||||||
|
void em4x50_info(em4x50_data_t *etd);
|
||||||
|
void em4x50_write(em4x50_data_t *etd);
|
||||||
|
void em4x50_write_password(em4x50_data_t *etd);
|
||||||
|
|
||||||
|
#endif /* EM4X50_H */
|
|
@ -35,7 +35,7 @@ static uint32_t felica_lasttime_prox2air_start;
|
||||||
static void iso18092_setup(uint8_t fpga_minor_mode);
|
static void iso18092_setup(uint8_t fpga_minor_mode);
|
||||||
static uint8_t felica_select_card(felica_card_select_t *card);
|
static uint8_t felica_select_card(felica_card_select_t *card);
|
||||||
static void TransmitFor18092_AsReader(uint8_t *frame, int len, uint32_t *timing, uint8_t power, uint8_t highspeed);
|
static void TransmitFor18092_AsReader(uint8_t *frame, int len, uint32_t *timing, uint8_t power, uint8_t highspeed);
|
||||||
bool WaitForFelicaReply(uint16_t maxbytes);
|
static bool WaitForFelicaReply(uint16_t maxbytes);
|
||||||
|
|
||||||
static void iso18092_set_timeout(uint32_t timeout) {
|
static void iso18092_set_timeout(uint32_t timeout) {
|
||||||
felica_timeout = timeout + (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER) / (16 * 8) + 2;
|
felica_timeout = timeout + (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER) / (16 * 8) + 2;
|
||||||
|
|
|
@ -16,8 +16,8 @@
|
||||||
/// Calculates the value of the CSR DLYBCT field given the desired delay (in ns)
|
/// Calculates the value of the CSR DLYBCT field given the desired delay (in ns)
|
||||||
#define SPI_DLYBCT(delay, masterClock) ((uint32_t) ((((masterClock) / 1000000) * (delay)) / 32000) << 24)
|
#define SPI_DLYBCT(delay, masterClock) ((uint32_t) ((((masterClock) / 1000000) * (delay)) / 32000) << 24)
|
||||||
|
|
||||||
|
static uint32_t FLASHMEM_SPIBAUDRATE = FLASH_BAUD;
|
||||||
uint32_t FLASHMEM_SPIBAUDRATE = FLASH_BAUD;
|
#define FASTFLASH (FLASHMEM_SPIBAUDRATE > FLASH_MINFAST)
|
||||||
|
|
||||||
void FlashmemSetSpiBaudrate(uint32_t baudrate) {
|
void FlashmemSetSpiBaudrate(uint32_t baudrate) {
|
||||||
FLASHMEM_SPIBAUDRATE = baudrate;
|
FLASHMEM_SPIBAUDRATE = baudrate;
|
||||||
|
@ -523,7 +523,7 @@ void Flash_EraseChip(void) {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void Flashmem_print_status(void) {
|
void Flashmem_print_status(void) {
|
||||||
DbpString(_BLUE_("Flash memory"));
|
DbpString(_CYAN_("Flash memory"));
|
||||||
Dbprintf(" Baudrate................" _GREEN_("%d MHz"), FLASHMEM_SPIBAUDRATE / 1000000);
|
Dbprintf(" Baudrate................" _GREEN_("%d MHz"), FLASHMEM_SPIBAUDRATE / 1000000);
|
||||||
|
|
||||||
if (!FlashInit()) {
|
if (!FlashInit()) {
|
||||||
|
@ -562,7 +562,7 @@ void Flashmem_print_info(void) {
|
||||||
|
|
||||||
if (!FlashInit()) return;
|
if (!FlashInit()) return;
|
||||||
|
|
||||||
DbpString(_BLUE_("Flash memory dictionary loaded"));
|
DbpString(_CYAN_("Flash memory dictionary loaded"));
|
||||||
|
|
||||||
// load dictionary offsets.
|
// load dictionary offsets.
|
||||||
uint8_t keysum[2];
|
uint8_t keysum[2];
|
||||||
|
|
|
@ -106,8 +106,6 @@
|
||||||
#define FLASH_FASTBAUD MCK
|
#define FLASH_FASTBAUD MCK
|
||||||
#define FLASH_MINBAUD FLASH_FASTBAUD
|
#define FLASH_MINBAUD FLASH_FASTBAUD
|
||||||
|
|
||||||
#define FASTFLASH (FLASHMEM_SPIBAUDRATE > FLASH_MINFAST)
|
|
||||||
|
|
||||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
|
||||||
|
|
||||||
void FlashmemSetSpiBaudrate(uint32_t baudrate);
|
void FlashmemSetSpiBaudrate(uint32_t baudrate);
|
||||||
|
|
|
@ -17,10 +17,19 @@
|
||||||
#include "ticks.h"
|
#include "ticks.h"
|
||||||
#include "dbprint.h"
|
#include "dbprint.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "zlib.h"
|
|
||||||
#include "fpga.h"
|
#include "fpga.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
|
|
||||||
|
#include "lz4.h" // uncompress
|
||||||
|
|
||||||
|
typedef struct lz4_stream_s {
|
||||||
|
LZ4_streamDecode_t *lz4StreamDecode;
|
||||||
|
char *next_in;
|
||||||
|
int avail_in;
|
||||||
|
} lz4_stream;
|
||||||
|
|
||||||
|
typedef lz4_stream *lz4_streamp;
|
||||||
|
|
||||||
// remember which version of the bitstream we have already downloaded to the FPGA
|
// remember which version of the bitstream we have already downloaded to the FPGA
|
||||||
static int downloaded_bitstream = 0;
|
static int downloaded_bitstream = 0;
|
||||||
|
|
||||||
|
@ -30,8 +39,6 @@ extern uint8_t _binary_obj_fpga_all_bit_z_start, _binary_obj_fpga_all_bit_z_end;
|
||||||
static uint8_t *fpga_image_ptr = NULL;
|
static uint8_t *fpga_image_ptr = NULL;
|
||||||
static uint32_t uncompressed_bytes_cnt;
|
static uint32_t uncompressed_bytes_cnt;
|
||||||
|
|
||||||
#define OUTPUT_BUFFER_LEN 80
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Set up the Serial Peripheral Interface as master
|
// Set up the Serial Peripheral Interface as master
|
||||||
// Used to write the FPGA config word
|
// Used to write the FPGA config word
|
||||||
|
@ -180,18 +187,23 @@ bool FpgaSetupSscDma(uint8_t *buf, int len) {
|
||||||
// Uncompress (inflate) the FPGA data. Returns one decompressed byte with
|
// Uncompress (inflate) the FPGA data. Returns one decompressed byte with
|
||||||
// each call.
|
// each call.
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
static int get_from_fpga_combined_stream(z_streamp compressed_fpga_stream, uint8_t *output_buffer) {
|
static int get_from_fpga_combined_stream(lz4_streamp compressed_fpga_stream, uint8_t *output_buffer) {
|
||||||
if (fpga_image_ptr == compressed_fpga_stream->next_out) { // need more data
|
if (fpga_image_ptr == output_buffer + FPGA_RING_BUFFER_BYTES) { // need more data
|
||||||
compressed_fpga_stream->next_out = output_buffer;
|
|
||||||
compressed_fpga_stream->avail_out = OUTPUT_BUFFER_LEN;
|
|
||||||
fpga_image_ptr = output_buffer;
|
fpga_image_ptr = output_buffer;
|
||||||
int res = inflate(compressed_fpga_stream, Z_SYNC_FLUSH);
|
int cmp_bytes;
|
||||||
|
memcpy(&cmp_bytes, compressed_fpga_stream->next_in, sizeof(int));
|
||||||
if (res != Z_OK)
|
compressed_fpga_stream->next_in += 4;
|
||||||
Dbprintf("inflate returned: %d, %s", res, compressed_fpga_stream->msg);
|
compressed_fpga_stream->avail_in -= cmp_bytes + 4;
|
||||||
|
int res = LZ4_decompress_safe_continue(compressed_fpga_stream->lz4StreamDecode,
|
||||||
if (res < 0)
|
compressed_fpga_stream->next_in,
|
||||||
|
(char *)output_buffer,
|
||||||
|
cmp_bytes,
|
||||||
|
FPGA_RING_BUFFER_BYTES);
|
||||||
|
if (res <= 0) {
|
||||||
|
Dbprintf("inflate returned: %d", res);
|
||||||
return res;
|
return res;
|
||||||
|
}
|
||||||
|
compressed_fpga_stream->next_in += cmp_bytes;
|
||||||
}
|
}
|
||||||
uncompressed_bytes_cnt++;
|
uncompressed_bytes_cnt++;
|
||||||
return *fpga_image_ptr++;
|
return *fpga_image_ptr++;
|
||||||
|
@ -202,8 +214,8 @@ static int get_from_fpga_combined_stream(z_streamp compressed_fpga_stream, uint8
|
||||||
// are combined into one big file:
|
// are combined into one big file:
|
||||||
// 288 bytes from FPGA file 1, followed by 288 bytes from FGPA file 2, etc.
|
// 288 bytes from FPGA file 1, followed by 288 bytes from FGPA file 2, etc.
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
static int get_from_fpga_stream(int bitstream_version, z_streamp compressed_fpga_stream, uint8_t *output_buffer) {
|
static int get_from_fpga_stream(int bitstream_version, lz4_streamp compressed_fpga_stream, uint8_t *output_buffer) {
|
||||||
while ((uncompressed_bytes_cnt / FPGA_INTERLEAVE_SIZE) % fpga_bitstream_num != (bitstream_version - 1)) {
|
while ((uncompressed_bytes_cnt / FPGA_INTERLEAVE_SIZE) % g_fpga_bitstream_num != (bitstream_version - 1)) {
|
||||||
// skip undesired data belonging to other bitstream_versions
|
// skip undesired data belonging to other bitstream_versions
|
||||||
get_from_fpga_combined_stream(compressed_fpga_stream, output_buffer);
|
get_from_fpga_combined_stream(compressed_fpga_stream, output_buffer);
|
||||||
}
|
}
|
||||||
|
@ -211,37 +223,23 @@ static int get_from_fpga_stream(int bitstream_version, z_streamp compressed_fpga
|
||||||
return get_from_fpga_combined_stream(compressed_fpga_stream, output_buffer);
|
return get_from_fpga_combined_stream(compressed_fpga_stream, output_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static voidpf fpga_inflate_malloc(voidpf opaque, uInt items, uInt size) {
|
|
||||||
return BigBuf_malloc(items * size);
|
|
||||||
}
|
|
||||||
|
|
||||||
// free eventually allocated BigBuf memory
|
|
||||||
static void fpga_inflate_free(voidpf opaque, voidpf address) {
|
|
||||||
BigBuf_free();
|
|
||||||
BigBuf_Clear_ext(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// Initialize decompression of the respective (HF or LF) FPGA stream
|
// Initialize decompression of the respective (HF or LF) FPGA stream
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
static bool reset_fpga_stream(int bitstream_version, z_streamp compressed_fpga_stream, uint8_t *output_buffer) {
|
static bool reset_fpga_stream(int bitstream_version, lz4_streamp compressed_fpga_stream, uint8_t *output_buffer) {
|
||||||
uint8_t header[FPGA_BITSTREAM_FIXED_HEADER_SIZE];
|
uint8_t header[FPGA_BITSTREAM_FIXED_HEADER_SIZE];
|
||||||
|
|
||||||
uncompressed_bytes_cnt = 0;
|
uncompressed_bytes_cnt = 0;
|
||||||
|
|
||||||
// initialize z_stream structure for inflate:
|
// initialize z_stream structure for inflate:
|
||||||
compressed_fpga_stream->next_in = &_binary_obj_fpga_all_bit_z_start;
|
compressed_fpga_stream->next_in = (char *)&_binary_obj_fpga_all_bit_z_start;
|
||||||
compressed_fpga_stream->avail_in = &_binary_obj_fpga_all_bit_z_end - &_binary_obj_fpga_all_bit_z_start;
|
compressed_fpga_stream->avail_in = &_binary_obj_fpga_all_bit_z_end - &_binary_obj_fpga_all_bit_z_start;
|
||||||
compressed_fpga_stream->next_out = output_buffer;
|
|
||||||
compressed_fpga_stream->avail_out = OUTPUT_BUFFER_LEN;
|
|
||||||
compressed_fpga_stream->zalloc = &fpga_inflate_malloc;
|
|
||||||
compressed_fpga_stream->zfree = &fpga_inflate_free;
|
|
||||||
|
|
||||||
int res = inflateInit2(compressed_fpga_stream, 0);
|
int res = LZ4_setStreamDecode(compressed_fpga_stream->lz4StreamDecode, NULL, 0);
|
||||||
if (res < 0)
|
if (res == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
fpga_image_ptr = output_buffer;
|
fpga_image_ptr = output_buffer + FPGA_RING_BUFFER_BYTES;
|
||||||
|
|
||||||
for (uint16_t i = 0; i < FPGA_BITSTREAM_FIXED_HEADER_SIZE; i++)
|
for (uint16_t i = 0; i < FPGA_BITSTREAM_FIXED_HEADER_SIZE; i++)
|
||||||
header[i] = get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer);
|
header[i] = get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer);
|
||||||
|
@ -266,7 +264,7 @@ static void DownloadFPGA_byte(uint8_t w) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Download the fpga image starting at current stream position with length FpgaImageLen bytes
|
// Download the fpga image starting at current stream position with length FpgaImageLen bytes
|
||||||
static void DownloadFPGA(int bitstream_version, int FpgaImageLen, z_streamp compressed_fpga_stream, uint8_t *output_buffer) {
|
static void DownloadFPGA(int bitstream_version, int FpgaImageLen, lz4_streamp compressed_fpga_stream, uint8_t *output_buffer) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
AT91C_BASE_PIOA->PIO_OER = GPIO_FPGA_ON;
|
AT91C_BASE_PIOA->PIO_OER = GPIO_FPGA_ON;
|
||||||
|
@ -348,7 +346,7 @@ static void DownloadFPGA(int bitstream_version, int FpgaImageLen, z_streamp comp
|
||||||
* (big endian), <length> bytes content. Except for section 'e' which has 4 bytes
|
* (big endian), <length> bytes content. Except for section 'e' which has 4 bytes
|
||||||
* length.
|
* length.
|
||||||
*/
|
*/
|
||||||
static int bitparse_find_section(int bitstream_version, char section_name, uint32_t *section_length, z_streamp compressed_fpga_stream, uint8_t *output_buffer) {
|
static int bitparse_find_section(int bitstream_version, char section_name, uint32_t *section_length, lz4_streamp compressed_fpga_stream, uint8_t *output_buffer) {
|
||||||
int result = 0;
|
int result = 0;
|
||||||
#define MAX_FPGA_BIT_STREAM_HEADER_SEARCH 100 // maximum number of bytes to search for the requested section
|
#define MAX_FPGA_BIT_STREAM_HEADER_SEARCH 100 // maximum number of bytes to search for the requested section
|
||||||
uint16_t numbytes = 0;
|
uint16_t numbytes = 0;
|
||||||
|
@ -407,8 +405,6 @@ void FpgaDownloadAndGo(int bitstream_version) {
|
||||||
|
|
||||||
// Send waiting time extension request as this will take a while
|
// Send waiting time extension request as this will take a while
|
||||||
send_wtx(1500);
|
send_wtx(1500);
|
||||||
z_stream compressed_fpga_stream;
|
|
||||||
uint8_t output_buffer[OUTPUT_BUFFER_LEN] = {0x00};
|
|
||||||
|
|
||||||
bool verbose = (DBGLEVEL > 3);
|
bool verbose = (DBGLEVEL > 3);
|
||||||
|
|
||||||
|
@ -416,6 +412,11 @@ void FpgaDownloadAndGo(int bitstream_version) {
|
||||||
BigBuf_free();
|
BigBuf_free();
|
||||||
BigBuf_Clear_ext(verbose);
|
BigBuf_Clear_ext(verbose);
|
||||||
|
|
||||||
|
lz4_stream compressed_fpga_stream;
|
||||||
|
LZ4_streamDecode_t lz4StreamDecode_body = {{ 0 }};
|
||||||
|
compressed_fpga_stream.lz4StreamDecode = &lz4StreamDecode_body;
|
||||||
|
uint8_t *output_buffer = BigBuf_malloc(FPGA_RING_BUFFER_BYTES);
|
||||||
|
|
||||||
if (!reset_fpga_stream(bitstream_version, &compressed_fpga_stream, output_buffer))
|
if (!reset_fpga_stream(bitstream_version, &compressed_fpga_stream, output_buffer))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -425,8 +426,6 @@ void FpgaDownloadAndGo(int bitstream_version) {
|
||||||
downloaded_bitstream = bitstream_version;
|
downloaded_bitstream = bitstream_version;
|
||||||
}
|
}
|
||||||
|
|
||||||
inflateEnd(&compressed_fpga_stream);
|
|
||||||
|
|
||||||
// turn off antenna
|
// turn off antenna
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
|
|
||||||
|
@ -508,8 +507,8 @@ void SetAdcMuxFor(uint32_t whichGpio) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Fpga_print_status(void) {
|
void Fpga_print_status(void) {
|
||||||
DbpString(_BLUE_("Currently loaded FPGA image"));
|
DbpString(_CYAN_("Current FPGA image"));
|
||||||
Dbprintf(" mode....................%s", fpga_version_information[downloaded_bitstream - 1]);
|
Dbprintf(" mode....................%s", g_fpga_version_information[downloaded_bitstream - 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
int FpgaGetCurrent(void) {
|
int FpgaGetCurrent(void) {
|
||||||
|
|
|
@ -1471,10 +1471,9 @@ char *json_vasprintf(const char *fmt, va_list ap) {
|
||||||
|
|
||||||
char *json_asprintf(const char *fmt, ...) WEAK;
|
char *json_asprintf(const char *fmt, ...) WEAK;
|
||||||
char *json_asprintf(const char *fmt, ...) {
|
char *json_asprintf(const char *fmt, ...) {
|
||||||
char *result = NULL;
|
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
result = json_vasprintf(fmt, ap);
|
char *result = json_vasprintf(fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,29 +18,21 @@
|
||||||
#include "appmain.h"
|
#include "appmain.h"
|
||||||
#include "cmd.h"
|
#include "cmd.h"
|
||||||
|
|
||||||
static void RAMFUNC optimizedSniff(void) {
|
static void RAMFUNC optimizedSniff(uint16_t *dest, uint16_t dsize) {
|
||||||
int n = BigBuf_max_traceLen() / sizeof(uint16_t); // take all memory
|
while (dsize > 0) {
|
||||||
|
|
||||||
uint16_t *dest = (uint16_t *)BigBuf_get_addr();
|
|
||||||
uint16_t *destend = dest + n - 1;
|
|
||||||
|
|
||||||
// Reading data loop
|
|
||||||
while (dest <= destend) {
|
|
||||||
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
|
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
|
||||||
*dest = (uint16_t)(AT91C_BASE_SSC->SSC_RHR);
|
*dest = (uint16_t)(AT91C_BASE_SSC->SSC_RHR);
|
||||||
dest++;
|
dest++;
|
||||||
|
dsize -= sizeof(dsize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//setting tracelen - important! it was set by buffer overflow before
|
|
||||||
set_tracelen(BigBuf_max_traceLen());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void HfSniff(int samplesToSkip, int triggersToSkip) {
|
int HfSniff(uint32_t samplesToSkip, uint32_t triggersToSkip, uint16_t *len) {
|
||||||
BigBuf_free();
|
BigBuf_free();
|
||||||
BigBuf_Clear();
|
BigBuf_Clear_ext(false);
|
||||||
|
|
||||||
Dbprintf("Skipping first %d sample pairs, Skipping %d triggers.\n", samplesToSkip, triggersToSkip);
|
Dbprintf("Skipping first %d sample pairs, Skipping %d triggers", samplesToSkip, triggersToSkip);
|
||||||
int trigger_cnt = 0;
|
|
||||||
|
|
||||||
LED_D_ON();
|
LED_D_ON();
|
||||||
|
|
||||||
|
@ -57,37 +49,68 @@ void HfSniff(int samplesToSkip, int triggersToSkip) {
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SNOOP);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SNOOP);
|
||||||
SpinDelay(100);
|
SpinDelay(100);
|
||||||
|
|
||||||
uint16_t r = 0;
|
*len = (BigBuf_max_traceLen() & 0xFFFE);
|
||||||
while (!BUTTON_PRESS() && !data_available()) {
|
uint8_t *mem = BigBuf_malloc(*len);
|
||||||
|
|
||||||
|
uint32_t trigger_cnt = 0;
|
||||||
|
uint16_t r = 0, interval = 0;
|
||||||
|
|
||||||
|
bool pressed = false;
|
||||||
|
while (pressed == false) {
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
|
|
||||||
|
// cancel w usb command.
|
||||||
|
if (interval == 2000) {
|
||||||
|
if (data_available())
|
||||||
|
break;
|
||||||
|
|
||||||
|
interval = 0;
|
||||||
|
} else {
|
||||||
|
interval++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if trigger is reached
|
||||||
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
|
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
|
||||||
r = (uint16_t)AT91C_BASE_SSC->SSC_RHR;
|
r = (uint16_t)AT91C_BASE_SSC->SSC_RHR;
|
||||||
r = MAX(r & 0xff, r >> 8);
|
|
||||||
if (r >= 180) { // 0xB4 ??
|
r = MAX(r & 0xFF, r >> 8);
|
||||||
if (++trigger_cnt > triggersToSkip)
|
|
||||||
|
// 180 (0xB4) arbitary value to see if a strong RF field is near.
|
||||||
|
if (r > 180) {
|
||||||
|
|
||||||
|
if (++trigger_cnt > triggersToSkip) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pressed = BUTTON_PRESS();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!BUTTON_PRESS()) {
|
if (pressed == false) {
|
||||||
int waitcount = samplesToSkip; // lets wait 40000 ticks of pck0
|
|
||||||
while (waitcount != 0) {
|
|
||||||
|
|
||||||
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY))
|
// skip samples loop
|
||||||
waitcount--;
|
while (samplesToSkip != 0) {
|
||||||
|
|
||||||
|
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
|
||||||
|
samplesToSkip--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
optimizedSniff((uint16_t*)mem, *len);
|
||||||
|
|
||||||
|
if (DBGLEVEL >= DBG_INFO) {
|
||||||
|
Dbprintf("Trigger kicked in (%d >= 180)", r);
|
||||||
|
Dbprintf("Collected %u samples", *len);
|
||||||
}
|
}
|
||||||
optimizedSniff();
|
|
||||||
Dbprintf("Trigger kicked! Value: %d, Dumping Samples Hispeed now.", r);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Resetting Frame mode (First set in fpgaloader.c)
|
//Resetting Frame mode (First set in fpgaloader.c)
|
||||||
AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) | AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0);
|
AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) | AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0);
|
||||||
|
|
||||||
DbpString("HF Sniffing end");
|
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
|
||||||
LED_D_OFF();
|
LED_D_OFF();
|
||||||
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
|
BigBuf_free();
|
||||||
|
return (pressed) ? PM3_EOPABORTED : PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HfPlotDownload(void) {
|
void HfPlotDownload(void) {
|
||||||
|
|
|
@ -12,6 +12,8 @@
|
||||||
#ifndef __HFSNOOP_H
|
#ifndef __HFSNOOP_H
|
||||||
#define __HFSNOOP_H
|
#define __HFSNOOP_H
|
||||||
|
|
||||||
void HfSniff(int, int);
|
#include "proxmark3_arm.h"
|
||||||
|
|
||||||
|
int HfSniff(uint32_t samplesToSkip, uint32_t triggersToSkip, uint16_t *len);
|
||||||
void HfPlotDownload(void);
|
void HfPlotDownload(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -48,8 +48,8 @@ static bool bCrypto;
|
||||||
// Is in auth stage
|
// Is in auth stage
|
||||||
static bool bAuthenticating;
|
static bool bAuthenticating;
|
||||||
// Successful password auth
|
// Successful password auth
|
||||||
bool bSelecting;
|
static bool bSelecting;
|
||||||
bool bCollision;
|
static bool bCollision;
|
||||||
static bool bPwd;
|
static bool bPwd;
|
||||||
static bool bSuccessful;
|
static bool bSuccessful;
|
||||||
|
|
||||||
|
@ -89,14 +89,14 @@ static uint8_t password[4];
|
||||||
static uint8_t NrAr[8];
|
static uint8_t NrAr[8];
|
||||||
static uint8_t key[8];
|
static uint8_t key[8];
|
||||||
static uint8_t writedata[4];
|
static uint8_t writedata[4];
|
||||||
uint8_t logdata_0[4], logdata_1[4];
|
static uint8_t logdata_0[4], logdata_1[4];
|
||||||
uint8_t nonce[4];
|
static uint8_t nonce[4];
|
||||||
bool key_no;
|
static bool key_no;
|
||||||
static uint64_t cipher_state;
|
static uint64_t cipher_state;
|
||||||
|
|
||||||
int16_t blocknr;
|
static int16_t blocknr;
|
||||||
size_t flipped_bit = 0;
|
static size_t flipped_bit = 0;
|
||||||
uint32_t byte_value = 0;
|
static uint32_t byte_value = 0;
|
||||||
|
|
||||||
static int hitag2_reset(void) {
|
static int hitag2_reset(void) {
|
||||||
tag.state = TAG_STATE_RESET;
|
tag.state = TAG_STATE_RESET;
|
||||||
|
@ -997,7 +997,7 @@ void SniffHitag2(void) {
|
||||||
|
|
||||||
lf_init(false, false);
|
lf_init(false, false);
|
||||||
|
|
||||||
logging = false;
|
g_logging = false;
|
||||||
|
|
||||||
size_t periods = 0;
|
size_t periods = 0;
|
||||||
uint8_t periods_bytes[4];
|
uint8_t periods_bytes[4];
|
||||||
|
@ -1031,8 +1031,8 @@ void SniffHitag2(void) {
|
||||||
|
|
||||||
// Test if we detected the first reader modulation edge
|
// Test if we detected the first reader modulation edge
|
||||||
if (periods != 0) {
|
if (periods != 0) {
|
||||||
if (logging == false) {
|
if (g_logging == false) {
|
||||||
logging = true;
|
g_logging = true;
|
||||||
LED_D_ON();
|
LED_D_ON();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1238,7 +1238,7 @@ void SimulateHitag2(bool tag_mem_supplied, uint8_t *data) {
|
||||||
// Check if frame was captured
|
// Check if frame was captured
|
||||||
if (rxlen > 4) {
|
if (rxlen > 4) {
|
||||||
|
|
||||||
LogTrace(rx, nbytes(rxlen), response, 0, NULL, true);
|
LogTrace(rx, nbytes(rxlen), response, response, NULL, true);
|
||||||
|
|
||||||
// Process the incoming frame (rx) and prepare the outgoing frame (tx)
|
// Process the incoming frame (rx) and prepare the outgoing frame (tx)
|
||||||
hitag2_handle_reader_command(rx, rxlen, tx, &txlen);
|
hitag2_handle_reader_command(rx, rxlen, tx, &txlen);
|
||||||
|
|
|
@ -17,9 +17,9 @@
|
||||||
#define READP0CMD "1100000111"
|
#define READP0CMD "1100000111"
|
||||||
#define ERROR_RESPONSE "F402889C"
|
#define ERROR_RESPONSE "F402889C"
|
||||||
|
|
||||||
extern const uint8_t Hitag2Sync[5];
|
static const uint8_t Hitag2Sync[5];
|
||||||
extern bool CryptoActive;
|
static bool CryptoActive;
|
||||||
extern Hitag_State Hitag_Crypto_State;
|
static Hitag_State Hitag_Crypto_State;
|
||||||
|
|
||||||
// hitag2_crack implements the first crack algorithm described in the paper,
|
// hitag2_crack implements the first crack algorithm described in the paper,
|
||||||
// Gone In 360 Seconds by Verdult, Garcia and Balasch.
|
// Gone In 360 Seconds by Verdult, Garcia and Balasch.
|
||||||
|
|
|
@ -48,8 +48,7 @@ static int temp2 = 0;
|
||||||
static int sof_bits; // number of start-of-frame bits
|
static int sof_bits; // number of start-of-frame bits
|
||||||
static uint8_t pwdh0, pwdl0, pwdl1; // password bytes
|
static uint8_t pwdh0, pwdl0, pwdl1; // password bytes
|
||||||
static uint32_t rnd = 0x74124485; // randomnumber
|
static uint32_t rnd = 0x74124485; // randomnumber
|
||||||
size_t blocknr;
|
static bool end = false;
|
||||||
bool end = false;
|
|
||||||
//#define SENDBIT_TEST
|
//#define SENDBIT_TEST
|
||||||
|
|
||||||
/* array index 3 2 1 0 // bytes in sim.bin file are 0 1 2 3
|
/* array index 3 2 1 0 // bytes in sim.bin file are 0 1 2 3
|
||||||
|
@ -1040,7 +1039,7 @@ void SimulateHitagSTag(bool tag_mem_supplied, uint8_t *data) {
|
||||||
// Check if frame was captured
|
// Check if frame was captured
|
||||||
if (rxlen > 0) {
|
if (rxlen > 0) {
|
||||||
// frame_count++;
|
// frame_count++;
|
||||||
LogTrace(rx, nbytes(rxlen), response, 0, NULL, true);
|
LogTrace(rx, nbytes(rxlen), response, response, NULL, true);
|
||||||
|
|
||||||
// Disable timer 1 with external trigger to avoid triggers during our own modulation
|
// Disable timer 1 with external trigger to avoid triggers during our own modulation
|
||||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
|
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
|
||||||
|
@ -1282,7 +1281,7 @@ void ReadHitagS(hitag_function htf, hitag_data *htd) {
|
||||||
// Check if frame was captured and store it
|
// Check if frame was captured and store it
|
||||||
if (rxlen > 0) {
|
if (rxlen > 0) {
|
||||||
// frame_count++;
|
// frame_count++;
|
||||||
LogTrace(rx, nbytes(rxlen), response, 0, NULL, false);
|
LogTrace(rx, nbytes(rxlen), response, response, NULL, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// By default reset the transmission buffer
|
// By default reset the transmission buffer
|
||||||
|
@ -1411,7 +1410,7 @@ void ReadHitagS(hitag_function htf, hitag_data *htd) {
|
||||||
// Add transmitted frame to total count
|
// Add transmitted frame to total count
|
||||||
if (txlen > 0) {
|
if (txlen > 0) {
|
||||||
// frame_count++;
|
// frame_count++;
|
||||||
LogTrace(tx, nbytes(txlen), HITAG_T_WAIT_2, 0, NULL, true);
|
LogTrace(tx, nbytes(txlen), HITAG_T_WAIT_2, HITAG_T_WAIT_2, NULL, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
hitagS_receive_frame(rx, &rxlen, &response);
|
hitagS_receive_frame(rx, &rxlen, &response);
|
||||||
|
@ -1539,7 +1538,7 @@ void WritePageHitagS(hitag_function htf, hitag_data *htd, int page) {
|
||||||
// Check if frame was captured and store it
|
// Check if frame was captured and store it
|
||||||
if (rxlen > 0) {
|
if (rxlen > 0) {
|
||||||
// frame_count++;
|
// frame_count++;
|
||||||
LogTrace(rx, nbytes(rxlen), response, 0, NULL, false);
|
LogTrace(rx, nbytes(rxlen), response, response, NULL, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
//check for valid input
|
//check for valid input
|
||||||
|
@ -1626,7 +1625,7 @@ void WritePageHitagS(hitag_function htf, hitag_data *htd, int page) {
|
||||||
// Add transmitted frame to total count
|
// Add transmitted frame to total count
|
||||||
if (txlen > 0) {
|
if (txlen > 0) {
|
||||||
// frame_count++;
|
// frame_count++;
|
||||||
LogTrace(tx, nbytes(txlen), HITAG_T_WAIT_2, 0, NULL, true);
|
LogTrace(tx, nbytes(txlen), HITAG_T_WAIT_2, HITAG_T_WAIT_2, NULL, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
hitagS_receive_frame(rx, &rxlen, &response);
|
hitagS_receive_frame(rx, &rxlen, &response);
|
||||||
|
@ -1733,7 +1732,7 @@ void check_challenges(bool file_given, uint8_t *data) {
|
||||||
// Check if frame was captured and store it
|
// Check if frame was captured and store it
|
||||||
if (rxlen > 0) {
|
if (rxlen > 0) {
|
||||||
// frame_count++;
|
// frame_count++;
|
||||||
LogTrace(rx, nbytes(rxlen), response, 0, NULL, false);
|
LogTrace(rx, nbytes(rxlen), response, response, NULL, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *tx = txbuf;
|
uint8_t *tx = txbuf;
|
||||||
|
@ -1865,7 +1864,7 @@ void check_challenges(bool file_given, uint8_t *data) {
|
||||||
// Add transmitted frame to total count
|
// Add transmitted frame to total count
|
||||||
if (txlen > 0) {
|
if (txlen > 0) {
|
||||||
// frame_count++;
|
// frame_count++;
|
||||||
LogTrace(tx, nbytes(txlen), HITAG_T_WAIT_2, 0, NULL, true);
|
LogTrace(tx, nbytes(txlen), HITAG_T_WAIT_2, HITAG_T_WAIT_2, NULL, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
hitagS_receive_frame(rx, &rxlen, &response);
|
hitagS_receive_frame(rx, &rxlen, &response);
|
||||||
|
|
43
armsrc/i2c.c
43
armsrc/i2c.c
|
@ -27,12 +27,12 @@
|
||||||
#define SDA_H HIGH(GPIO_SDA)
|
#define SDA_H HIGH(GPIO_SDA)
|
||||||
#define SDA_L LOW(GPIO_SDA)
|
#define SDA_L LOW(GPIO_SDA)
|
||||||
|
|
||||||
#define SCL_read (AT91C_BASE_PIOA->PIO_PDSR & GPIO_SCL)
|
#define SCL_read ((AT91C_BASE_PIOA->PIO_PDSR & GPIO_SCL) == GPIO_SCL)
|
||||||
#define SDA_read (AT91C_BASE_PIOA->PIO_PDSR & GPIO_SDA)
|
#define SDA_read ((AT91C_BASE_PIOA->PIO_PDSR & GPIO_SDA) == GPIO_SDA)
|
||||||
|
|
||||||
#define I2C_ERROR "I2C_WaitAck Error"
|
#define I2C_ERROR "I2C_WaitAck Error"
|
||||||
|
|
||||||
volatile unsigned long c;
|
static volatile uint32_t c;
|
||||||
|
|
||||||
// Direct use the loop to delay. 6 instructions loop, Masterclock 48MHz,
|
// Direct use the loop to delay. 6 instructions loop, Masterclock 48MHz,
|
||||||
// delay=1 is about 200kbps
|
// delay=1 is about 200kbps
|
||||||
|
@ -47,6 +47,12 @@ static void __attribute__((optimize("O0"))) I2CSpinDelayClk(uint16_t delay) {
|
||||||
#define I2C_DELAY_2CLK I2CSpinDelayClk(2)
|
#define I2C_DELAY_2CLK I2CSpinDelayClk(2)
|
||||||
#define I2C_DELAY_XCLK(x) I2CSpinDelayClk((x))
|
#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
|
#define ISO7618_MAX_FRAME 255
|
||||||
|
|
||||||
// try i2c bus recovery at 100kHz = 5us high, 5us low
|
// try i2c bus recovery at 100kHz = 5us high, 5us low
|
||||||
|
@ -69,6 +75,7 @@ void I2C_recovery(void) {
|
||||||
//a STOP signal (SDA from low to high while CLK is high)
|
//a STOP signal (SDA from low to high while CLK is high)
|
||||||
SDA_L;
|
SDA_L;
|
||||||
WaitUS(5);
|
WaitUS(5);
|
||||||
|
|
||||||
SCL_H;
|
SCL_H;
|
||||||
WaitUS(2);
|
WaitUS(2);
|
||||||
SDA_H;
|
SDA_H;
|
||||||
|
@ -127,11 +134,11 @@ void I2C_Reset_EnterMainProgram(void) {
|
||||||
StartTicks();
|
StartTicks();
|
||||||
I2C_init();
|
I2C_init();
|
||||||
I2C_SetResetStatus(0, 0, 0);
|
I2C_SetResetStatus(0, 0, 0);
|
||||||
WaitMS(30);
|
I2C_DELAY_30ms;
|
||||||
I2C_SetResetStatus(1, 0, 0);
|
I2C_SetResetStatus(1, 0, 0);
|
||||||
WaitMS(30);
|
I2C_DELAY_30ms;
|
||||||
I2C_SetResetStatus(1, 1, 1);
|
I2C_SetResetStatus(1, 1, 1);
|
||||||
WaitMS(10);
|
I2C_DELAY_10ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset the SIM_Adapter, then enter the bootloader program
|
// Reset the SIM_Adapter, then enter the bootloader program
|
||||||
|
@ -140,9 +147,9 @@ void I2C_Reset_EnterBootloader(void) {
|
||||||
StartTicks();
|
StartTicks();
|
||||||
I2C_init();
|
I2C_init();
|
||||||
I2C_SetResetStatus(0, 1, 1);
|
I2C_SetResetStatus(0, 1, 1);
|
||||||
WaitMS(100);
|
I2C_DELAY_100ms;
|
||||||
I2C_SetResetStatus(1, 1, 1);
|
I2C_SetResetStatus(1, 1, 1);
|
||||||
WaitMS(10);
|
I2C_DELAY_10ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait for the clock to go High.
|
// Wait for the clock to go High.
|
||||||
|
@ -180,13 +187,13 @@ static bool WaitSCL_L(void) {
|
||||||
// It timeout reading response from card
|
// It timeout reading response from card
|
||||||
// Which ever comes first
|
// Which ever comes first
|
||||||
static bool WaitSCL_L_timeout(void) {
|
static bool WaitSCL_L_timeout(void) {
|
||||||
volatile uint16_t delay = 1800;
|
volatile uint32_t delay = 18000;
|
||||||
while (delay--) {
|
while (delay--) {
|
||||||
// exit on SCL LOW
|
// exit on SCL LOW
|
||||||
if (!SCL_read)
|
if (!SCL_read)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
WaitMS(1);
|
I2C_DELAY_100us;
|
||||||
}
|
}
|
||||||
return (delay == 0);
|
return (delay == 0);
|
||||||
}
|
}
|
||||||
|
@ -218,7 +225,7 @@ static bool I2C_WaitForSim(void) {
|
||||||
// 8051 speaks with smart card.
|
// 8051 speaks with smart card.
|
||||||
// 1000*50*3.07 = 153.5ms
|
// 1000*50*3.07 = 153.5ms
|
||||||
// 1byte transfer == 1ms with max frame being 256bytes
|
// 1byte transfer == 1ms with max frame being 256bytes
|
||||||
if (!WaitSCL_H_delay(10 * 1000 * 50))
|
if (!WaitSCL_H_delay(20 * 1000 * 50))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -433,7 +440,9 @@ int16_t I2C_BufferRead(uint8_t *data, uint8_t len, uint8_t device_cmd, uint8_t d
|
||||||
|
|
||||||
// extra wait 500us (514us measured)
|
// extra wait 500us (514us measured)
|
||||||
// 200us (xx measured)
|
// 200us (xx measured)
|
||||||
WaitUS(600);
|
// WaitUS(600);
|
||||||
|
I2C_DELAY_600us;
|
||||||
|
|
||||||
bool bBreak = true;
|
bool bBreak = true;
|
||||||
uint16_t readcount = 0;
|
uint16_t readcount = 0;
|
||||||
|
|
||||||
|
@ -474,7 +483,7 @@ int16_t I2C_BufferRead(uint8_t *data, uint8_t len, uint8_t device_cmd, uint8_t d
|
||||||
*data = (uint8_t)tmp & 0xFF;
|
*data = (uint8_t)tmp & 0xFF;
|
||||||
|
|
||||||
len--;
|
len--;
|
||||||
// 读取的第一个字节为后续长度
|
|
||||||
// The first byte in response is the message length
|
// The first byte in response is the message length
|
||||||
if (!readcount && (len > *data)) {
|
if (!readcount && (len > *data)) {
|
||||||
len = *data;
|
len = *data;
|
||||||
|
@ -601,7 +610,7 @@ bool I2C_WriteFW(uint8_t *data, uint8_t len, uint8_t msb, uint8_t lsb, uint8_t d
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2C_print_status(void) {
|
void I2C_print_status(void) {
|
||||||
DbpString(_BLUE_("Smart card module (ISO 7816)"));
|
DbpString(_CYAN_("Smart card module (ISO 7816)"));
|
||||||
uint8_t maj, min;
|
uint8_t maj, min;
|
||||||
if (I2C_get_version(&maj, &min) == PM3_SUCCESS)
|
if (I2C_get_version(&maj, &min) == PM3_SUCCESS)
|
||||||
Dbprintf(" version................." _YELLOW_("v%x.%02d"), maj, min);
|
Dbprintf(" version................." _YELLOW_("v%x.%02d"), maj, min);
|
||||||
|
@ -617,9 +626,8 @@ int I2C_get_version(uint8_t *maj, uint8_t *min) {
|
||||||
*maj = resp[0];
|
*maj = resp[0];
|
||||||
*min = resp[1];
|
*min = resp[1];
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
} else {
|
|
||||||
return PM3_EDEVNOTSUPP;
|
|
||||||
}
|
}
|
||||||
|
return PM3_EDEVNOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Will read response from smart card module, retries 3 times to get the data.
|
// Will read response from smart card module, retries 3 times to get the data.
|
||||||
|
@ -799,7 +807,8 @@ void SmartCardUpgrade(uint64_t arg0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// writing takes time.
|
// writing takes time.
|
||||||
WaitMS(50);
|
// WaitMS(50);
|
||||||
|
I2C_DELAY_100ms;
|
||||||
|
|
||||||
// read
|
// read
|
||||||
res = I2C_ReadFW(verfiydata, size, msb, lsb, I2C_DEVICE_ADDRESS_BOOT);
|
res = I2C_ReadFW(verfiydata, size, msb, lsb, I2C_DEVICE_ADDRESS_BOOT);
|
||||||
|
|
|
@ -1802,7 +1802,7 @@ static void ReaderTransmitIClass_ext(uint8_t *frame, int len, int wait) {
|
||||||
TransmitIClassCommand(ToSend, ToSendMax, &wait);
|
TransmitIClassCommand(ToSend, ToSendMax, &wait);
|
||||||
LED_A_ON();
|
LED_A_ON();
|
||||||
|
|
||||||
LogTrace(frame, len, rsamples, rsamples, NULL, true);
|
LogTrace(frame, len, g_rsamples, g_rsamples, NULL, true);
|
||||||
}
|
}
|
||||||
static void ReaderTransmitIClass(uint8_t *frame, int len) {
|
static void ReaderTransmitIClass(uint8_t *frame, int len) {
|
||||||
ReaderTransmitIClass_ext(frame, len, 330);
|
ReaderTransmitIClass_ext(frame, len, 330);
|
||||||
|
@ -1867,7 +1867,7 @@ static int ReaderReceiveIClass(uint8_t *receivedAnswer) {
|
||||||
if (GetIClassAnswer(receivedAnswer, 0, NULL) == false)
|
if (GetIClassAnswer(receivedAnswer, 0, NULL) == false)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
LogTrace(receivedAnswer, Demod.len, rsamples, rsamples, NULL, false);
|
LogTrace(receivedAnswer, Demod.len, g_rsamples, g_rsamples, NULL, false);
|
||||||
return Demod.len;
|
return Demod.len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,9 +31,9 @@ static uint32_t iso14a_timeout;
|
||||||
// if iso14443a not active - transmit/receive dont try to execute
|
// if iso14443a not active - transmit/receive dont try to execute
|
||||||
static bool hf_field_active = false;
|
static bool hf_field_active = false;
|
||||||
|
|
||||||
uint8_t colpos = 0;
|
static uint8_t colpos = 0;
|
||||||
int rsamples = 0;
|
int g_rsamples = 0;
|
||||||
uint8_t trigger = 0;
|
uint8_t g_trigger = 0;
|
||||||
// the block number for the ISO14443-4 PCB
|
// the block number for the ISO14443-4 PCB
|
||||||
static uint8_t iso14_pcb_blocknum = 0;
|
static uint8_t iso14_pcb_blocknum = 0;
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ static uint8_t iso14_pcb_blocknum = 0;
|
||||||
#define DELAY_ARM2AIR_AS_READER (4*16 + 8*16 + 8 + 8 + 1)
|
#define DELAY_ARM2AIR_AS_READER (4*16 + 8*16 + 8 + 8 + 1)
|
||||||
|
|
||||||
// The FPGA will report its internal sending delay in
|
// The FPGA will report its internal sending delay in
|
||||||
uint16_t FpgaSendQueueDelay;
|
static uint16_t FpgaSendQueueDelay;
|
||||||
// the 5 first bits are the number of bits buffered in mod_sig_buf
|
// the 5 first bits are the number of bits buffered in mod_sig_buf
|
||||||
// the last three bits are the remaining ticks/2 after the mod_sig_buf shift
|
// the last three bits are the remaining ticks/2 after the mod_sig_buf shift
|
||||||
#define DELAY_FPGA_QUEUE (FpgaSendQueueDelay<<1)
|
#define DELAY_FPGA_QUEUE (FpgaSendQueueDelay<<1)
|
||||||
|
@ -123,7 +123,7 @@ static uint32_t LastProxToAirDuration;
|
||||||
#define SEC_Z 0xc0
|
#define SEC_Z 0xc0
|
||||||
|
|
||||||
void iso14a_set_trigger(bool enable) {
|
void iso14a_set_trigger(bool enable) {
|
||||||
trigger = enable;
|
g_trigger = enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
void iso14a_set_timeout(uint32_t timeout) {
|
void iso14a_set_timeout(uint32_t timeout) {
|
||||||
|
@ -184,7 +184,7 @@ static tUart14a Uart;
|
||||||
// 0011 - a 2 tick wide pause, or a three tick wide pause shifted left
|
// 0011 - a 2 tick wide pause, or a three tick wide pause shifted left
|
||||||
// 0111 - a 2 tick wide pause shifted left
|
// 0111 - a 2 tick wide pause shifted left
|
||||||
// 1001 - a 2 tick wide pause shifted right
|
// 1001 - a 2 tick wide pause shifted right
|
||||||
const bool Mod_Miller_LUT[] = {
|
static const bool Mod_Miller_LUT[] = {
|
||||||
false, true, false, true, false, false, false, true,
|
false, true, false, true, false, false, false, true,
|
||||||
false, true, false, false, false, false, false, false
|
false, true, false, false, false, false, false, false
|
||||||
};
|
};
|
||||||
|
@ -351,11 +351,11 @@ RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time) {
|
||||||
// 8 ticks modulated: A collision. Save the collision position and treat as Sequence D
|
// 8 ticks modulated: A collision. Save the collision position and treat as Sequence D
|
||||||
// Note 1: the bitstream may start at any time. We therefore need to sync.
|
// Note 1: the bitstream may start at any time. We therefore need to sync.
|
||||||
// Note 2: parameter offset is used to determine the position of the parity bits (required for the anticollision command only)
|
// Note 2: parameter offset is used to determine the position of the parity bits (required for the anticollision command only)
|
||||||
tDemod14a Demod;
|
static tDemod14a Demod;
|
||||||
|
|
||||||
// Lookup-Table to decide if 4 raw bits are a modulation.
|
// Lookup-Table to decide if 4 raw bits are a modulation.
|
||||||
// We accept three or four "1" in any position
|
// We accept three or four "1" in any position
|
||||||
const bool Mod_Manchester_LUT[] = {
|
static const bool Mod_Manchester_LUT[] = {
|
||||||
false, false, false, false, false, false, false, true,
|
false, false, false, false, false, false, false, true,
|
||||||
false, false, false, true, false, true, true, true
|
false, false, false, true, false, true, true, true
|
||||||
};
|
};
|
||||||
|
@ -889,7 +889,7 @@ bool prepare_tag_modulation(tag_response_info_t *response_info, size_t max_buffe
|
||||||
|
|
||||||
// Make sure we do not exceed the free buffer space
|
// Make sure we do not exceed the free buffer space
|
||||||
if (ToSendMax > max_buffer_size) {
|
if (ToSendMax > max_buffer_size) {
|
||||||
Dbprintf("Out of memory, when modulating bits for tag answer:");
|
Dbprintf("ToSend buffer, Out-of-bound, when modulating bits for tag answer:");
|
||||||
Dbhexdump(response_info->response_n, response_info->response, false);
|
Dbhexdump(response_info->response_n, response_info->response, false);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -980,14 +980,26 @@ bool SimulateIso14443aInit(int tagType, int flags, uint8_t *data, tag_response_i
|
||||||
// some first pages of UL/NTAG dump is special data
|
// some first pages of UL/NTAG dump is special data
|
||||||
mfu_dump_t *mfu_header = (mfu_dump_t *) BigBuf_get_EM_addr();
|
mfu_dump_t *mfu_header = (mfu_dump_t *) BigBuf_get_EM_addr();
|
||||||
*pages = MAX(mfu_header->pages, 19);
|
*pages = MAX(mfu_header->pages, 19);
|
||||||
|
|
||||||
// counters and tearing flags
|
// counters and tearing flags
|
||||||
for (int i = 0; i < 3; i++) {
|
// for old dumps with all zero headers, we need to set default values.
|
||||||
|
for (uint8_t i = 0; i < 3; i++) {
|
||||||
|
|
||||||
counters[i] = le24toh(mfu_header->counter_tearing[i]);
|
counters[i] = le24toh(mfu_header->counter_tearing[i]);
|
||||||
tearings[i] = mfu_header->counter_tearing[i][3];
|
|
||||||
|
if (mfu_header->counter_tearing[i][3] != 0x00) {
|
||||||
|
tearings[i] = mfu_header->counter_tearing[i][3];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GET_VERSION
|
// GET_VERSION
|
||||||
memcpy(rVERSION, mfu_header->version, 8);
|
if (memcmp(mfu_header->version, "\x00\x00\x00\x00\x00\x00\x00\x00", 8) == 0) {
|
||||||
|
memcpy(rVERSION, "\x00\x04\x04\x02\x01\x00\x11\x03", 8);
|
||||||
|
} else {
|
||||||
|
memcpy(rVERSION, mfu_header->version, 8);
|
||||||
|
}
|
||||||
AddCrc14A(rVERSION, sizeof(rVERSION) - 2);
|
AddCrc14A(rVERSION, sizeof(rVERSION) - 2);
|
||||||
|
|
||||||
// READ_SIG
|
// READ_SIG
|
||||||
memcpy(rSIGN, mfu_header->signature, 32);
|
memcpy(rSIGN, mfu_header->signature, 32);
|
||||||
AddCrc14A(rSIGN, sizeof(rSIGN) - 2);
|
AddCrc14A(rSIGN, sizeof(rSIGN) - 2);
|
||||||
|
@ -2015,13 +2027,6 @@ int EmSendPrecompiledCmd(tag_response_info_t *p_response) {
|
||||||
LastTimeProxToAirStart * 16 + DELAY_ARM2AIR_AS_TAG,
|
LastTimeProxToAirStart * 16 + DELAY_ARM2AIR_AS_TAG,
|
||||||
(LastTimeProxToAirStart + p_response->ProxToAirDuration) * 16 + DELAY_ARM2AIR_AS_TAG,
|
(LastTimeProxToAirStart + p_response->ProxToAirDuration) * 16 + DELAY_ARM2AIR_AS_TAG,
|
||||||
par);
|
par);
|
||||||
|
|
||||||
if (DBGLEVEL >= DBG_EXTENDED) {
|
|
||||||
Dbprintf("response_info->response %02X", p_response->response);
|
|
||||||
Dbprintf("response_info->response_n %02X", p_response->response_n);
|
|
||||||
Dbprintf("response_info->par %02X", &(p_response->par));
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2145,7 +2150,7 @@ void ReaderTransmitBitsPar(uint8_t *frame, uint16_t bits, uint8_t *par, uint32_t
|
||||||
CodeIso14443aBitsAsReaderPar(frame, bits, par);
|
CodeIso14443aBitsAsReaderPar(frame, bits, par);
|
||||||
// Send command to tag
|
// Send command to tag
|
||||||
TransmitFor14443a(ToSend, ToSendMax, timing);
|
TransmitFor14443a(ToSend, ToSendMax, timing);
|
||||||
if (trigger) LED_A_ON();
|
if (g_trigger) LED_A_ON();
|
||||||
|
|
||||||
LogTrace(frame, nbytes(bits), (LastTimeProxToAirStart << 4) + DELAY_ARM2AIR_AS_READER, ((LastTimeProxToAirStart + LastProxToAirDuration) << 4) + DELAY_ARM2AIR_AS_READER, par, true);
|
LogTrace(frame, nbytes(bits), (LastTimeProxToAirStart << 4) + DELAY_ARM2AIR_AS_READER, ((LastTimeProxToAirStart + LastProxToAirDuration) << 4) + DELAY_ARM2AIR_AS_READER, par, true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -641,9 +641,9 @@ void SimulateIso14443bTag(uint32_t pupi) {
|
||||||
if (cardSTATE == SIM_NOFIELD) {
|
if (cardSTATE == SIM_NOFIELD) {
|
||||||
|
|
||||||
#if defined RDV4
|
#if defined RDV4
|
||||||
vHf = (MAX_ADC_HF_VOLTAGE_RDV40 * AvgAdc(ADC_CHAN_HF_RDV40)) >> 10;
|
vHf = (MAX_ADC_HF_VOLTAGE_RDV40 * SumAdc(ADC_CHAN_HF_RDV40, 32)) >> 15;
|
||||||
#else
|
#else
|
||||||
vHf = (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10;
|
vHf = (MAX_ADC_HF_VOLTAGE * SumAdc(ADC_CHAN_HF, 32)) >> 15;
|
||||||
#endif
|
#endif
|
||||||
if (vHf > MF_MINFIELDV) {
|
if (vHf > MF_MINFIELDV) {
|
||||||
cardSTATE = SIM_IDLE;
|
cardSTATE = SIM_IDLE;
|
||||||
|
@ -1150,9 +1150,9 @@ static void CodeAndTransmit14443bAsReader(const uint8_t *cmd, int len) {
|
||||||
|
|
||||||
TransmitFor14443b_AsReader();
|
TransmitFor14443b_AsReader();
|
||||||
|
|
||||||
if (trigger) LED_A_ON();
|
if (g_trigger) LED_A_ON();
|
||||||
|
|
||||||
LogTrace(cmd, len, time_start, GetCountSspClk() - time_start, NULL, true);
|
LogTrace(cmd, len, time_start, GetCountSspClk(), NULL, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sends an APDU to the tag
|
/* Sends an APDU to the tag
|
||||||
|
@ -1578,7 +1578,7 @@ void RAMFUNC SniffIso14443b(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void iso14b_set_trigger(bool enable) {
|
static void iso14b_set_trigger(bool enable) {
|
||||||
trigger = enable;
|
g_trigger = enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -431,7 +431,7 @@ static int GetIso15693AnswerFromTag(uint8_t *received, int *elapsed) {
|
||||||
getNext = !getNext;
|
getNext = !getNext;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
time_stop = GetCountSspClk() - time_0 ;
|
time_stop = GetCountSspClk();
|
||||||
int len = DemodAnswer(received, buf, counter);
|
int len = DemodAnswer(received, buf, counter);
|
||||||
LogTrace(received, len, time_0 << 4, time_stop << 4, NULL, false);
|
LogTrace(received, len, time_0 << 4, time_stop << 4, NULL, false);
|
||||||
BigBuf_free();
|
BigBuf_free();
|
||||||
|
@ -478,7 +478,7 @@ static int GetIso15693AnswerFromSniff(uint8_t *received, int *samples, int *elap
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
time_stop = GetCountSspClk() - time_0;
|
time_stop = GetCountSspClk();
|
||||||
int k = DemodAnswer(received, buf, counter);
|
int k = DemodAnswer(received, buf, counter);
|
||||||
LogTrace(received, k, time_0 << 4, time_stop << 4, NULL, false);
|
LogTrace(received, k, time_0 << 4, time_stop << 4, NULL, false);
|
||||||
return k;
|
return k;
|
||||||
|
@ -522,7 +522,7 @@ void AcquireRawAdcSamplesIso15693(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LogTrace(cmd, CMD_ID_RESP, time_start << 4, (GetCountSspClk() - time_start) << 4, NULL, true);
|
LogTrace(cmd, CMD_ID_RESP, time_start << 4, GetCountSspClk() << 4, NULL, true);
|
||||||
|
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
|
||||||
|
|
||||||
|
@ -723,7 +723,7 @@ static int SendDataTag(uint8_t *send, int sendlen, bool init, int speed, uint8_t
|
||||||
uint32_t time_start = GetCountSspClk();
|
uint32_t time_start = GetCountSspClk();
|
||||||
|
|
||||||
TransmitTo15693Tag(ToSend, ToSendMax, &t_samples, &wait);
|
TransmitTo15693Tag(ToSend, ToSendMax, &t_samples, &wait);
|
||||||
LogTrace(send, sendlen, time_start << 4, (GetCountSspClk() - time_start) << 4, NULL, true);
|
LogTrace(send, sendlen, time_start << 4, GetCountSspClk() << 4, NULL, true);
|
||||||
|
|
||||||
// Now wait for a response
|
// Now wait for a response
|
||||||
if (outdata != NULL) {
|
if (outdata != NULL) {
|
||||||
|
@ -825,7 +825,7 @@ void ReaderIso15693(uint32_t parameter) {
|
||||||
uint8_t cmd[CMD_ID_RESP] = {0};
|
uint8_t cmd[CMD_ID_RESP] = {0};
|
||||||
BuildIdentifyRequest(cmd);
|
BuildIdentifyRequest(cmd);
|
||||||
TransmitTo15693Tag(ToSend, ToSendMax, &tsamples, &wait);
|
TransmitTo15693Tag(ToSend, ToSendMax, &tsamples, &wait);
|
||||||
LogTrace(cmd, CMD_ID_RESP, time_start << 4, (GetCountSspClk() - time_start) << 4, NULL, true);
|
LogTrace(cmd, CMD_ID_RESP, time_start << 4, GetCountSspClk() << 4, NULL, true);
|
||||||
|
|
||||||
// Now wait for a response
|
// Now wait for a response
|
||||||
answerLen1 = GetIso15693AnswerFromTag(answer1, &elapsed) ;
|
answerLen1 = GetIso15693AnswerFromTag(answer1, &elapsed) ;
|
||||||
|
@ -906,7 +906,7 @@ void SimTagIso15693(uint32_t parameter, uint8_t *uid) {
|
||||||
|
|
||||||
time_start = GetCountSspClk();
|
time_start = GetCountSspClk();
|
||||||
TransmitTo15693Reader(ToSend, ToSendMax, &tsamples, &wait);
|
TransmitTo15693Reader(ToSend, ToSendMax, &tsamples, &wait);
|
||||||
LogTrace(cmd, CMD_INV_RESP, time_start << 4, (GetCountSspClk() - time_start) << 4, NULL, true);
|
LogTrace(cmd, CMD_INV_RESP, time_start << 4, GetCountSspClk() << 4, NULL, true);
|
||||||
|
|
||||||
if (DBGLEVEL >= DBG_EXTENDED) {
|
if (DBGLEVEL >= DBG_EXTENDED) {
|
||||||
Dbprintf("[+] %d octets read from reader command: %x %x %x %x %x %x %x %x", ans,
|
Dbprintf("[+] %d octets read from reader command: %x %x %x %x %x %x %x %x", ans,
|
||||||
|
|
|
@ -64,8 +64,7 @@ static uint32_t last_frame_end; /* ts of last bit of previews rx or tx frame */
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// I/O interface abstraction (FPGA -> ARM)
|
// I/O interface abstraction (FPGA -> ARM)
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
static uint8_t rx_byte_from_fpga(void) {
|
||||||
static inline uint8_t rx_byte_from_fpga(void) {
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
|
|
||||||
|
@ -93,11 +92,7 @@ static inline uint8_t rx_byte_from_fpga(void) {
|
||||||
// Note: The SSC receiver is never synchronized the calculation may be performed
|
// Note: The SSC receiver is never synchronized the calculation may be performed
|
||||||
// on a i/q pair from two subsequent correlations, but does not matter.
|
// on a i/q pair from two subsequent correlations, but does not matter.
|
||||||
// Note: inlining this function would fail with -Os
|
// Note: inlining this function would fail with -Os
|
||||||
#ifdef __OPTIMIZE_SIZE__
|
|
||||||
static int32_t sample_power(void) {
|
static int32_t sample_power(void) {
|
||||||
#else
|
|
||||||
static inline int32_t sample_power(void) {
|
|
||||||
#endif
|
|
||||||
int32_t q = (int8_t)rx_byte_from_fpga();
|
int32_t q = (int8_t)rx_byte_from_fpga();
|
||||||
q = ABS(q);
|
q = ABS(q);
|
||||||
int32_t i = (int8_t)rx_byte_from_fpga();
|
int32_t i = (int8_t)rx_byte_from_fpga();
|
||||||
|
@ -113,7 +108,9 @@ static inline int32_t sample_power(void) {
|
||||||
//
|
//
|
||||||
// Note: The demodulator would be drifting (18.9us * 5 != 100us), rx_frame
|
// Note: The demodulator would be drifting (18.9us * 5 != 100us), rx_frame
|
||||||
// has a delay loop that aligns rx_bit calls to the TAG tx timeslots.
|
// has a delay loop that aligns rx_bit calls to the TAG tx timeslots.
|
||||||
static inline bool rx_bit(void) {
|
|
||||||
|
// Note: inlining this function would fail with -Os
|
||||||
|
static bool rx_bit(void) {
|
||||||
int32_t power;
|
int32_t power;
|
||||||
|
|
||||||
for (size_t i = 0; i < 5; ++i) {
|
for (size_t i = 0; i < 5; ++i) {
|
||||||
|
@ -132,7 +129,7 @@ static inline bool rx_bit(void) {
|
||||||
// be circumvented, but the adventage over bitbang would be little.
|
// be circumvented, but the adventage over bitbang would be little.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
static inline void tx_bit(bool bit) {
|
static void tx_bit(bool bit) {
|
||||||
// insert pause
|
// insert pause
|
||||||
LOW(GPIO_SSC_DOUT);
|
LOW(GPIO_SSC_DOUT);
|
||||||
last_frame_end += RWD_TIME_PAUSE;
|
last_frame_end += RWD_TIME_PAUSE;
|
||||||
|
|
|
@ -66,11 +66,7 @@ static uint32_t last_frame_end; /* ts of last bit of previews rx or tx frame */
|
||||||
|
|
||||||
// Returns true if a pulse/pause is received within timeout
|
// Returns true if a pulse/pause is received within timeout
|
||||||
// Note: inlining this function would fail with -Os
|
// Note: inlining this function would fail with -Os
|
||||||
#ifdef __OPTIMIZE_SIZE__
|
|
||||||
static bool wait_for(bool value, const uint32_t timeout) {
|
static bool wait_for(bool value, const uint32_t timeout) {
|
||||||
#else
|
|
||||||
static inline bool wait_for(bool value, const uint32_t timeout) {
|
|
||||||
#endif
|
|
||||||
while ((bool)(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_DIN) != value) {
|
while ((bool)(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_DIN) != value) {
|
||||||
if (GetCountSspClk() > timeout) {
|
if (GetCountSspClk() > timeout) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -88,7 +84,7 @@ static inline bool wait_for(bool value, const uint32_t timeout) {
|
||||||
// - A bit length >80.2us is a 1
|
// - A bit length >80.2us is a 1
|
||||||
// - A bit length <80.2us is a 0
|
// - A bit length <80.2us is a 0
|
||||||
// - A bit length >148.6us is a code violation
|
// - A bit length >148.6us is a code violation
|
||||||
static inline int8_t rx_bit(void) {
|
static int8_t rx_bit(void) {
|
||||||
// backup ts for threshold calculation
|
// backup ts for threshold calculation
|
||||||
uint32_t bit_start = last_frame_end;
|
uint32_t bit_start = last_frame_end;
|
||||||
|
|
||||||
|
@ -132,11 +128,7 @@ static inline int8_t rx_bit(void) {
|
||||||
// not mandatory but results in a cleaner signal. tx_frame will disable
|
// not mandatory but results in a cleaner signal. tx_frame will disable
|
||||||
// the subcarrier when the frame is done.
|
// the subcarrier when the frame is done.
|
||||||
// Note: inlining this function would fail with -Os
|
// Note: inlining this function would fail with -Os
|
||||||
#ifdef __OPTIMIZE_SIZE__
|
|
||||||
static void tx_bit(bool bit) {
|
static void tx_bit(bool bit) {
|
||||||
#else
|
|
||||||
static inline void tx_bit(bool bit) {
|
|
||||||
#endif
|
|
||||||
LED_C_ON();
|
LED_C_ON();
|
||||||
|
|
||||||
if (bit) {
|
if (bit) {
|
||||||
|
|
|
@ -25,13 +25,18 @@
|
||||||
// T0 = timer/carrier = 1500kHz/125kHz = 1500000/125000 = 6
|
// T0 = timer/carrier = 1500kHz/125kHz = 1500000/125000 = 6
|
||||||
//#define HITAG_T0 3
|
//#define HITAG_T0 3
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Exported global variables
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool g_logging = true;
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
// Global variables
|
// Global variables
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
bool rising_edge = false;
|
static bool rising_edge = false;
|
||||||
bool logging = true;
|
static bool reader_mode = false;
|
||||||
bool reader_mode = false;
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
// Auxiliary functions
|
// Auxiliary functions
|
||||||
|
@ -46,8 +51,8 @@ bool lf_test_periods(size_t expected, size_t count) {
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
// Low frequency (LF) adc passthrough functionality
|
// Low frequency (LF) adc passthrough functionality
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
uint8_t previous_adc_val = 0;
|
static uint8_t previous_adc_val = 0;
|
||||||
uint8_t adc_avg = 0;
|
static uint8_t adc_avg = 0;
|
||||||
|
|
||||||
void lf_sample_mean(void) {
|
void lf_sample_mean(void) {
|
||||||
uint8_t periods = 0;
|
uint8_t periods = 0;
|
||||||
|
@ -90,7 +95,7 @@ static size_t lf_count_edge_periods_ex(size_t max, bool wait, bool detect_gap) {
|
||||||
adc_val = AT91C_BASE_SSC->SSC_RHR;
|
adc_val = AT91C_BASE_SSC->SSC_RHR;
|
||||||
periods++;
|
periods++;
|
||||||
|
|
||||||
if (logging) logSampleSimple(adc_val);
|
if (g_logging) logSampleSimple(adc_val);
|
||||||
|
|
||||||
// Only test field changes if state of adc values matter
|
// Only test field changes if state of adc values matter
|
||||||
if (wait == false) {
|
if (wait == false) {
|
||||||
|
@ -120,7 +125,7 @@ static size_t lf_count_edge_periods_ex(size_t max, bool wait, bool detect_gap) {
|
||||||
if (periods >= max) return 0;
|
if (periods >= max) return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (logging) logSampleSimple(0xFF);
|
if (g_logging) logSampleSimple(0xFF);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,7 +228,7 @@ void lf_init(bool reader, bool simulate) {
|
||||||
uint32_t bufsize = 10000;
|
uint32_t bufsize = 10000;
|
||||||
|
|
||||||
// use malloc
|
// use malloc
|
||||||
if (logging) initSampleBufferEx(&bufsize, true);
|
if (g_logging) initSampleBufferEx(&bufsize, true);
|
||||||
|
|
||||||
lf_sample_mean();
|
lf_sample_mean();
|
||||||
}
|
}
|
||||||
|
@ -269,7 +274,7 @@ size_t lf_detect_field_drop(size_t max) {
|
||||||
periods++;
|
periods++;
|
||||||
volatile uint8_t adc_val = AT91C_BASE_SSC->SSC_RHR;
|
volatile uint8_t adc_val = AT91C_BASE_SSC->SSC_RHR;
|
||||||
|
|
||||||
if (logging) logSampleSimple(adc_val);
|
if (g_logging) logSampleSimple(adc_val);
|
||||||
|
|
||||||
if (adc_val == 0) {
|
if (adc_val == 0) {
|
||||||
rising_edge = false;
|
rising_edge = false;
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
|
|
||||||
extern bool logging;
|
extern bool g_logging;
|
||||||
|
|
||||||
void lf_sample_mean(void);
|
void lf_sample_mean(void);
|
||||||
bool lf_test_periods(size_t expected, size_t count);
|
bool lf_test_periods(size_t expected, size_t count);
|
||||||
|
|
211
armsrc/lfops.c
211
armsrc/lfops.c
|
@ -171,7 +171,7 @@ t55xx_configurations_t T55xx_Timing = {
|
||||||
#define T55XX_LONGLEADINGREFERENCE 4 // Value to tell Write Bit to send long reference
|
#define T55XX_LONGLEADINGREFERENCE 4 // Value to tell Write Bit to send long reference
|
||||||
|
|
||||||
// ATA55xx shared presets & routines
|
// ATA55xx shared presets & routines
|
||||||
static uint32_t GetT55xxClockBit(uint32_t clock) {
|
static uint32_t GetT55xxClockBit(uint8_t clock) {
|
||||||
switch (clock) {
|
switch (clock) {
|
||||||
case 128:
|
case 128:
|
||||||
return T55x7_BITRATE_RF_128;
|
return T55x7_BITRATE_RF_128;
|
||||||
|
@ -198,7 +198,7 @@ void printT55xxConfig(void) {
|
||||||
|
|
||||||
#define PRN_NA sprintf(s + strlen(s), _RED_("N/A") " | ");
|
#define PRN_NA sprintf(s + strlen(s), _RED_("N/A") " | ");
|
||||||
|
|
||||||
DbpString(_BLUE_("LF T55XX config"));
|
DbpString(_CYAN_("LF T55XX config"));
|
||||||
Dbprintf(" [r] [a] [b] [c] [d] [e] [f] [g]");
|
Dbprintf(" [r] [a] [b] [c] [d] [e] [f] [g]");
|
||||||
Dbprintf(" mode |start|write|write|write| read|write|write");
|
Dbprintf(" mode |start|write|write|write| read|write|write");
|
||||||
Dbprintf(" | gap | gap | 0 | 1 | gap | 2 | 3");
|
Dbprintf(" | gap | gap | 0 | 1 | gap | 2 | 3");
|
||||||
|
@ -1224,32 +1224,52 @@ void CmdNRZsimTAG(uint8_t invert, uint8_t separator, uint8_t clk, uint16_t size,
|
||||||
}
|
}
|
||||||
|
|
||||||
// loop to get raw HID waveform then FSK demodulate the TAG ID from it
|
// loop to get raw HID waveform then FSK demodulate the TAG ID from it
|
||||||
void CmdHIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol) {
|
int lf_hid_watch(int findone, uint32_t *high, uint32_t *low) {
|
||||||
uint8_t *dest = BigBuf_get_addr();
|
|
||||||
size_t size;
|
size_t size;
|
||||||
uint32_t hi2 = 0, hi = 0, lo = 0;
|
uint32_t hi2 = 0, hi = 0, lo = 0;
|
||||||
int dummyIdx = 0;
|
int dummyIdx = 0;
|
||||||
// Configure to go in 125kHz listen mode
|
// Configure to go in 125kHz listen mode
|
||||||
LFSetupFPGAForADC(LF_DIVISOR_125, true);
|
LFSetupFPGAForADC(LF_DIVISOR_125, true);
|
||||||
|
|
||||||
|
uint8_t *dest = BigBuf_get_addr();
|
||||||
|
BigBuf_Clear_keep_EM();
|
||||||
|
clear_trace();
|
||||||
|
set_tracing(false);
|
||||||
|
|
||||||
//clear read buffer
|
//clear read buffer
|
||||||
BigBuf_Clear_keep_EM();
|
BigBuf_Clear_keep_EM();
|
||||||
|
|
||||||
while (!BUTTON_PRESS() && !data_available()) {
|
int res = PM3_SUCCESS;
|
||||||
|
uint16_t interval = 0;
|
||||||
|
while (BUTTON_PRESS() == false) {
|
||||||
|
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
if (ledcontrol) LED_A_ON();
|
|
||||||
|
// cancel w usb command.
|
||||||
|
if (interval == 4000) {
|
||||||
|
if (data_available()) {
|
||||||
|
res = PM3_EOPABORTED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
interval = 0;
|
||||||
|
} else {
|
||||||
|
interval++;
|
||||||
|
}
|
||||||
|
|
||||||
DoAcquisition_default(-1, false);
|
DoAcquisition_default(-1, false);
|
||||||
|
|
||||||
// FSK demodulator
|
// FSK demodulator
|
||||||
size = 50 * 128 * 2; //big enough to catch 2 sequences of largest format
|
// 50 * 128 * 2 - big enough to catch 2 sequences of largest format
|
||||||
|
size = MIN(12800, BigBuf_max_traceLen());
|
||||||
|
|
||||||
int idx = HIDdemodFSK(dest, &size, &hi2, &hi, &lo, &dummyIdx);
|
int idx = HIDdemodFSK(dest, &size, &hi2, &hi, &lo, &dummyIdx);
|
||||||
if (idx < 0) continue;
|
if (idx < 0) continue;
|
||||||
|
|
||||||
if (idx > 0 && lo > 0 && (size == 96 || size == 192)) {
|
if (idx > 0 && lo > 0 && (size == 96 || size == 192)) {
|
||||||
// go over previously decoded manchester data and decode into usable tag ID
|
// go over previously decoded manchester data and decode into usable tag ID
|
||||||
if (hi2 != 0) { //extra large HID tags 88/192 bits
|
if (hi2 != 0) { //extra large HID tags 88/192 bits
|
||||||
Dbprintf("TAG ID: %x%08x%08x (%d)",
|
Dbprintf("TAG ID: " _GREEN_("%x%08x%08x") " (%d)",
|
||||||
hi2,
|
hi2,
|
||||||
hi,
|
hi,
|
||||||
lo,
|
lo,
|
||||||
|
@ -1311,25 +1331,40 @@ void CmdHIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol)
|
||||||
hi2 = hi = lo = idx = 0;
|
hi2 = hi = lo = idx = 0;
|
||||||
}
|
}
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
DbpString("HID fsk demod stopped");
|
BigBuf_free();
|
||||||
if (ledcontrol) LED_A_OFF();
|
LEDsoff();
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
// loop to get raw HID waveform then FSK demodulate the TAG ID from it
|
// loop to get raw HID waveform then FSK demodulate the TAG ID from it
|
||||||
void CmdAWIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol) {
|
int lf_awid_watch(int findone, uint32_t *high, uint32_t *low) {
|
||||||
|
|
||||||
uint8_t *dest = BigBuf_get_addr();
|
|
||||||
size_t size;
|
size_t size;
|
||||||
int dummyIdx = 0;
|
int dummyIdx = 0;
|
||||||
|
|
||||||
|
uint8_t *dest = BigBuf_get_addr();
|
||||||
BigBuf_Clear_keep_EM();
|
BigBuf_Clear_keep_EM();
|
||||||
|
clear_trace();
|
||||||
|
set_tracing(false);
|
||||||
|
|
||||||
LFSetupFPGAForADC(LF_DIVISOR_125, true);
|
LFSetupFPGAForADC(LF_DIVISOR_125, true);
|
||||||
|
|
||||||
while (!BUTTON_PRESS() && !data_available()) {
|
int res = PM3_SUCCESS;
|
||||||
|
uint16_t interval = 0;
|
||||||
|
while (BUTTON_PRESS() == false) {
|
||||||
|
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
if (ledcontrol) LED_A_ON();
|
|
||||||
|
// cancel w usb command.
|
||||||
|
if (interval == 4000) {
|
||||||
|
if (data_available()) {
|
||||||
|
res = PM3_EOPABORTED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
interval = 0;
|
||||||
|
} else {
|
||||||
|
interval++;
|
||||||
|
}
|
||||||
|
|
||||||
DoAcquisition_default(-1, false);
|
DoAcquisition_default(-1, false);
|
||||||
// FSK demodulator
|
// FSK demodulator
|
||||||
|
@ -1380,20 +1415,19 @@ void CmdAWIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol)
|
||||||
uint32_t fac = bytebits_to_byte(dest + 9, 8);
|
uint32_t fac = bytebits_to_byte(dest + 9, 8);
|
||||||
uint32_t cardnum = bytebits_to_byte(dest + 17, 16);
|
uint32_t cardnum = bytebits_to_byte(dest + 17, 16);
|
||||||
uint32_t code1 = bytebits_to_byte(dest + 8, fmtLen);
|
uint32_t code1 = bytebits_to_byte(dest + 8, fmtLen);
|
||||||
Dbprintf("AWID Found - BitLength: %d, FC: %d, Card: %d - Wiegand: %x, Raw: %08x%08x%08x", fmtLen, fac, cardnum, code1, rawHi2, rawHi, rawLo);
|
Dbprintf("AWID Found - Bit length: " _GREEN_("%d") ", FC: " _GREEN_("%d") ", Card: " _GREEN_("%d") " - Wiegand: %x, Raw: %08x%08x%08x", fmtLen, fac, cardnum, code1, rawHi2, rawHi, rawLo);
|
||||||
} else {
|
} else {
|
||||||
uint32_t cardnum = bytebits_to_byte(dest + 8 + (fmtLen - 17), 16);
|
uint32_t cardnum = bytebits_to_byte(dest + 8 + (fmtLen - 17), 16);
|
||||||
if (fmtLen > 32) {
|
if (fmtLen > 32) {
|
||||||
uint32_t code1 = bytebits_to_byte(dest + 8, fmtLen - 32);
|
uint32_t code1 = bytebits_to_byte(dest + 8, fmtLen - 32);
|
||||||
uint32_t code2 = bytebits_to_byte(dest + 8 + (fmtLen - 32), 32);
|
uint32_t code2 = bytebits_to_byte(dest + 8 + (fmtLen - 32), 32);
|
||||||
Dbprintf("AWID Found - BitLength: %d -unknown BitLength- (%d) - Wiegand: %x%08x, Raw: %08x%08x%08x", fmtLen, cardnum, code1, code2, rawHi2, rawHi, rawLo);
|
Dbprintf("AWID Found - Bit length: " _GREEN_("%d") " -unknown bit length- (%d) - Wiegand: %x%08x, Raw: %08x%08x%08x", fmtLen, cardnum, code1, code2, rawHi2, rawHi, rawLo);
|
||||||
} else {
|
} else {
|
||||||
uint32_t code1 = bytebits_to_byte(dest + 8, fmtLen);
|
uint32_t code1 = bytebits_to_byte(dest + 8, fmtLen);
|
||||||
Dbprintf("AWID Found - BitLength: %d -unknown BitLength- (%d) - Wiegand: %x, Raw: %08x%08x%08x", fmtLen, cardnum, code1, rawHi2, rawHi, rawLo);
|
Dbprintf("AWID Found - Bit length: " _GREEN_("%d") " -unknown bit length- (%d) - Wiegand: %x, Raw: %08x%08x%08x", fmtLen, cardnum, code1, rawHi2, rawHi, rawLo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (findone) {
|
if (findone) {
|
||||||
if (ledcontrol) LED_A_OFF();
|
|
||||||
*high = rawHi;
|
*high = rawHi;
|
||||||
*low = rawLo;
|
*low = rawLo;
|
||||||
break;
|
break;
|
||||||
|
@ -1401,26 +1435,40 @@ void CmdAWIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol)
|
||||||
}
|
}
|
||||||
|
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
DbpString("AWID fsk demod stopped");
|
BigBuf_free();
|
||||||
if (ledcontrol) LED_A_OFF();
|
LEDsoff();
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CmdEM410xdemod(int findone, uint32_t *high, uint64_t *low, int ledcontrol) {
|
int lf_em410x_watch(int findone, uint32_t *high, uint64_t *low) {
|
||||||
uint8_t *dest = BigBuf_get_addr();
|
|
||||||
|
|
||||||
size_t size, idx = 0;
|
size_t size, idx = 0;
|
||||||
int clk = 0, invert = 0, maxErr = 20;
|
int clk = 0, invert = 0, maxErr = 20;
|
||||||
uint32_t hi = 0;
|
uint32_t hi = 0;
|
||||||
uint64_t lo = 0;
|
uint64_t lo = 0;
|
||||||
|
|
||||||
|
uint8_t *dest = BigBuf_get_addr();
|
||||||
|
clear_trace();
|
||||||
|
set_tracing(false);
|
||||||
BigBuf_Clear_keep_EM();
|
BigBuf_Clear_keep_EM();
|
||||||
|
|
||||||
LFSetupFPGAForADC(LF_DIVISOR_125, true);
|
LFSetupFPGAForADC(LF_DIVISOR_125, true);
|
||||||
|
|
||||||
while (!BUTTON_PRESS() && !data_available()) {
|
int res = PM3_SUCCESS;
|
||||||
|
uint16_t interval = 0;
|
||||||
|
while (BUTTON_PRESS() == false) {
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
if (ledcontrol) LED_A_ON();
|
|
||||||
|
// cancel w usb command.
|
||||||
|
if (interval == 4000) {
|
||||||
|
if (data_available()) {
|
||||||
|
res = PM3_EOPABORTED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
interval = 0;
|
||||||
|
} else {
|
||||||
|
interval++;
|
||||||
|
}
|
||||||
|
|
||||||
DoAcquisition_default(-1, false);
|
DoAcquisition_default(-1, false);
|
||||||
|
|
||||||
|
@ -1428,14 +1476,14 @@ void CmdEM410xdemod(int findone, uint32_t *high, uint64_t *low, int ledcontrol)
|
||||||
|
|
||||||
//askdemod and manchester decode
|
//askdemod and manchester decode
|
||||||
int errCnt = askdemod(dest, &size, &clk, &invert, maxErr, 0, 1);
|
int errCnt = askdemod(dest, &size, &clk, &invert, maxErr, 0, 1);
|
||||||
WDT_HIT();
|
|
||||||
|
|
||||||
if (errCnt > 50) continue;
|
if (errCnt > 50) continue;
|
||||||
|
|
||||||
|
WDT_HIT();
|
||||||
|
|
||||||
errCnt = Em410xDecode(dest, &size, &idx, &hi, &lo);
|
errCnt = Em410xDecode(dest, &size, &idx, &hi, &lo);
|
||||||
if (errCnt == 1) {
|
if (errCnt == 1) {
|
||||||
if (size == 128) {
|
if (size == 128) {
|
||||||
Dbprintf("EM XL TAG ID: %06x%08x%08x - (%05d_%03d_%08d)",
|
Dbprintf("EM XL TAG ID: " _GREEN_("%06x%08x%08x") " - ( %05d_%03d_%08d )",
|
||||||
hi,
|
hi,
|
||||||
(uint32_t)(lo >> 32),
|
(uint32_t)(lo >> 32),
|
||||||
(uint32_t)lo,
|
(uint32_t)lo,
|
||||||
|
@ -1443,7 +1491,7 @@ void CmdEM410xdemod(int findone, uint32_t *high, uint64_t *low, int ledcontrol)
|
||||||
(uint32_t)((lo >> 16LL) & 0xFF),
|
(uint32_t)((lo >> 16LL) & 0xFF),
|
||||||
(uint32_t)(lo & 0xFFFFFF));
|
(uint32_t)(lo & 0xFFFFFF));
|
||||||
} else {
|
} else {
|
||||||
Dbprintf("EM TAG ID: %02x%08x - (%05d_%03d_%08d)",
|
Dbprintf("EM TAG ID: " _GREEN_("%02x%08x") " - ( %05d_%03d_%08d )",
|
||||||
(uint32_t)(lo >> 32),
|
(uint32_t)(lo >> 32),
|
||||||
(uint32_t)lo,
|
(uint32_t)lo,
|
||||||
(uint32_t)(lo & 0xFFFF),
|
(uint32_t)(lo & 0xFFFF),
|
||||||
|
@ -1452,7 +1500,6 @@ void CmdEM410xdemod(int findone, uint32_t *high, uint64_t *low, int ledcontrol)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (findone) {
|
if (findone) {
|
||||||
if (ledcontrol) LED_A_OFF();
|
|
||||||
*high = hi;
|
*high = hi;
|
||||||
*low = lo;
|
*low = lo;
|
||||||
break;
|
break;
|
||||||
|
@ -1463,33 +1510,46 @@ void CmdEM410xdemod(int findone, uint32_t *high, uint64_t *low, int ledcontrol)
|
||||||
}
|
}
|
||||||
|
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
DbpString("EM man/ask demod stopped");
|
BigBuf_free();
|
||||||
if (ledcontrol) LED_A_OFF();
|
LEDsoff();
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CmdIOdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol) {
|
int lf_io_watch(int findone, uint32_t *high, uint32_t *low) {
|
||||||
|
|
||||||
uint8_t *dest = BigBuf_get_addr();
|
|
||||||
|
|
||||||
int dummyIdx = 0;
|
int dummyIdx = 0;
|
||||||
uint32_t code = 0, code2 = 0;
|
uint32_t code = 0, code2 = 0;
|
||||||
uint8_t version = 0, facilitycode = 0, crc = 0;
|
uint8_t version = 0, facilitycode = 0;
|
||||||
uint16_t number = 0, calccrc = 0;
|
uint16_t number = 0;
|
||||||
|
|
||||||
size_t size = BigBuf_max_traceLen();
|
|
||||||
|
|
||||||
|
uint8_t *dest = BigBuf_get_addr();
|
||||||
BigBuf_Clear_keep_EM();
|
BigBuf_Clear_keep_EM();
|
||||||
|
clear_trace();
|
||||||
|
set_tracing(false);
|
||||||
|
|
||||||
// Configure to go in 125kHz listen mode
|
// Configure to go in 125kHz listen mode
|
||||||
LFSetupFPGAForADC(LF_DIVISOR_125, true);
|
LFSetupFPGAForADC(LF_DIVISOR_125, true);
|
||||||
|
|
||||||
while (!BUTTON_PRESS() && !data_available()) {
|
int res = PM3_SUCCESS;
|
||||||
|
uint16_t interval = 0;
|
||||||
|
while (BUTTON_PRESS() == false) {
|
||||||
|
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
if (ledcontrol) LED_A_ON();
|
|
||||||
|
// cancel w usb command.
|
||||||
|
if (interval == 4000) {
|
||||||
|
if (data_available()) {
|
||||||
|
res = PM3_EOPABORTED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
interval = 0;
|
||||||
|
} else {
|
||||||
|
interval++;
|
||||||
|
}
|
||||||
|
|
||||||
DoAcquisition_default(-1, false);
|
DoAcquisition_default(-1, false);
|
||||||
|
|
||||||
size = MIN(12000, BigBuf_max_traceLen());
|
size_t size = MIN(12000, BigBuf_max_traceLen());
|
||||||
|
|
||||||
//fskdemod and get start index
|
//fskdemod and get start index
|
||||||
int idx = detectIOProx(dest, &size, &dummyIdx);
|
int idx = detectIOProx(dest, &size, &dummyIdx);
|
||||||
|
@ -1529,18 +1589,9 @@ void CmdIOdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol) {
|
||||||
facilitycode = bytebits_to_byte(dest + idx + 18, 8);
|
facilitycode = bytebits_to_byte(dest + idx + 18, 8);
|
||||||
number = (bytebits_to_byte(dest + idx + 36, 8) << 8) | (bytebits_to_byte(dest + idx + 45, 8)); //36,9
|
number = (bytebits_to_byte(dest + idx + 36, 8) << 8) | (bytebits_to_byte(dest + idx + 45, 8)); //36,9
|
||||||
|
|
||||||
crc = bytebits_to_byte(dest + idx + 54, 8);
|
Dbprintf("IO Prox " _GREEN_("XSF(%02d)%02x:%05d") " (%08x%08x) (%s)", version, facilitycode, number, code, code2);
|
||||||
for (uint8_t i = 1; i < 6; ++i)
|
|
||||||
calccrc += bytebits_to_byte(dest + idx + 9 * i, 8);
|
|
||||||
calccrc &= 0xff;
|
|
||||||
calccrc = 0xff - calccrc;
|
|
||||||
|
|
||||||
const char *crcStr = (crc == calccrc) ? "ok" : "!crc";
|
|
||||||
|
|
||||||
Dbprintf("IO Prox XSF(%02d)%02x:%05d (%08x%08x) [%02x %s]", version, facilitycode, number, code, code2, crc, crcStr);
|
|
||||||
// if we're only looking for one tag
|
|
||||||
if (findone) {
|
if (findone) {
|
||||||
if (ledcontrol) LED_A_OFF();
|
|
||||||
*high = code;
|
*high = code;
|
||||||
*low = code2;
|
*low = code2;
|
||||||
break;
|
break;
|
||||||
|
@ -1548,12 +1599,11 @@ void CmdIOdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol) {
|
||||||
code = code2 = 0;
|
code = code2 = 0;
|
||||||
version = facilitycode = 0;
|
version = facilitycode = 0;
|
||||||
number = 0;
|
number = 0;
|
||||||
calccrc = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
DbpString("IOProx fsk demod stopped");
|
BigBuf_free();
|
||||||
if (ledcontrol) LED_A_OFF();
|
LEDsoff();
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*------------------------------
|
/*------------------------------
|
||||||
|
@ -1571,7 +1621,7 @@ void TurnReadLFOn(uint32_t delay) {
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_ADC_READER_FIELD);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_ADC_READER_FIELD);
|
||||||
|
|
||||||
// measure antenna strength.
|
// measure antenna strength.
|
||||||
//int adcval = ((MAX_ADC_LF_VOLTAGE * AvgAdc(ADC_CHAN_LF)) >> 10);
|
//int adcval = ((MAX_ADC_LF_VOLTAGE * (SumAdc(ADC_CHAN_LF, 32) >> 1)) >> 14);
|
||||||
WaitUS(delay);
|
WaitUS(delay);
|
||||||
}
|
}
|
||||||
static void TurnReadLF_off(uint32_t delay) {
|
static void TurnReadLF_off(uint32_t delay) {
|
||||||
|
@ -2006,12 +2056,12 @@ void T55xx_ChkPwds(uint8_t flags) {
|
||||||
|
|
||||||
DbpString("[+] T55XX Check pwds using flashmemory starting");
|
DbpString("[+] T55XX Check pwds using flashmemory starting");
|
||||||
|
|
||||||
uint8_t ret = 0;
|
|
||||||
// First get baseline and setup LF mode.
|
// First get baseline and setup LF mode.
|
||||||
// tends to mess up BigBuf
|
// tends to mess up BigBuf
|
||||||
uint8_t *buf = BigBuf_get_addr();
|
uint8_t *buf = BigBuf_get_addr();
|
||||||
uint32_t b1, baseline = 0;
|
uint8_t ret = 0;
|
||||||
uint8_t downlink_mode = (flags >> 3) & 0x03;
|
uint8_t downlink_mode = (flags >> 3) & 0x03;
|
||||||
|
uint32_t b1, baseline = 0;
|
||||||
|
|
||||||
// collect baseline for failed attempt
|
// collect baseline for failed attempt
|
||||||
uint8_t x = 32;
|
uint8_t x = 32;
|
||||||
|
@ -2190,17 +2240,26 @@ void CopyVikingtoT55xx(uint8_t *blocks, uint8_t Q5) {
|
||||||
reply_ng(CMD_LF_VIKING_CLONE, PM3_SUCCESS, NULL, 0);
|
reply_ng(CMD_LF_VIKING_CLONE, PM3_SUCCESS, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int copy_em410x_to_t55xx(uint8_t card, uint8_t clock, uint32_t id_hi, uint32_t id_lo) {
|
||||||
|
|
||||||
// Define 9bit header for EM410x tags
|
// Define 9bit header for EM410x tags
|
||||||
#define EM410X_HEADER 0x1FF
|
#define EM410X_HEADER 0x1FF
|
||||||
#define EM410X_ID_LENGTH 40
|
#define EM410X_ID_LENGTH 40
|
||||||
|
|
||||||
void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo) {
|
uint32_t clockbits = 0;
|
||||||
|
if (card == 1) { //t55x7
|
||||||
|
clockbits = GetT55xxClockBit(clock);
|
||||||
|
if (clockbits == 0) {
|
||||||
|
Dbprintf("Invalid clock rate: %d", clock);
|
||||||
|
return PM3_EINVARG;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
uint64_t id = EM410X_HEADER;
|
uint64_t id = EM410X_HEADER;
|
||||||
uint64_t rev_id = 0; // reversed ID
|
uint64_t rev_id = 0; // reversed ID
|
||||||
int c_parity[4]; // column parity
|
int c_parity[4]; // column parity
|
||||||
int r_parity = 0; // row parity
|
int r_parity = 0; // row parity
|
||||||
uint32_t clock = 0;
|
|
||||||
|
|
||||||
// Reverse ID bits given as parameter (for simpler operations)
|
// Reverse ID bits given as parameter (for simpler operations)
|
||||||
for (i = 0; i < EM410X_ID_LENGTH; ++i) {
|
for (i = 0; i < EM410X_ID_LENGTH; ++i) {
|
||||||
|
@ -2250,33 +2309,29 @@ void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo) {
|
||||||
// Add stop bit
|
// Add stop bit
|
||||||
id <<= 1;
|
id <<= 1;
|
||||||
|
|
||||||
Dbprintf("Started writing %s tag ...", card ? "T55x7" : "T5555");
|
|
||||||
LED_D_ON();
|
LED_D_ON();
|
||||||
|
|
||||||
// Write EM410x ID
|
// Write EM410x ID
|
||||||
uint32_t data[] = {0, (uint32_t)(id >> 32), (uint32_t)(id & 0xFFFFFFFF)};
|
uint32_t data[] = {0, (uint32_t)(id >> 32), (uint32_t)(id & 0xFFFFFFFF)};
|
||||||
|
|
||||||
clock = (card & 0xFF00) >> 8;
|
// default to 64
|
||||||
clock = (clock == 0) ? 64 : clock;
|
clock = (clock == 0) ? 64 : clock;
|
||||||
Dbprintf("Clock rate: %d", clock);
|
Dbprintf("Clock rate: %d", clock);
|
||||||
if (card & 0xFF) { //t55x7
|
|
||||||
clock = GetT55xxClockBit(clock);
|
if (card == 1) { // T55x7
|
||||||
if (clock == 0) {
|
data[0] = clockbits | T55x7_MODULATION_MANCHESTER | (2 << T55x7_MAXBLOCK_SHIFT);
|
||||||
Dbprintf("Invalid clock rate: %d", clock);
|
} else { // T5555 (Q5)
|
||||||
return;
|
|
||||||
}
|
|
||||||
data[0] = clock | T55x7_MODULATION_MANCHESTER | (2 << T55x7_MAXBLOCK_SHIFT);
|
|
||||||
} else { //t5555 (Q5)
|
|
||||||
data[0] = T5555_SET_BITRATE(clock) | T5555_MODULATION_MANCHESTER | (2 << T5555_MAXBLOCK_SHIFT);
|
data[0] = T5555_SET_BITRATE(clock) | T5555_MODULATION_MANCHESTER | (2 << T5555_MAXBLOCK_SHIFT);
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteT55xx(data, 0, 3);
|
WriteT55xx(data, 0, 3);
|
||||||
|
|
||||||
LED_D_OFF();
|
LEDsoff();
|
||||||
Dbprintf("Tag %s written with 0x%08x%08x\n",
|
Dbprintf("Tag %s written with 0x%08x%08x\n",
|
||||||
card ? "T55x7" : "T5555",
|
card ? "T55x7" : "T5555",
|
||||||
(uint32_t)(id >> 32),
|
(uint32_t)(id >> 32),
|
||||||
(uint32_t)id);
|
(uint32_t)id);
|
||||||
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------
|
//-----------------------------------
|
||||||
|
@ -2289,10 +2344,10 @@ void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo) {
|
||||||
#define FWD_CMD_READ 0x9
|
#define FWD_CMD_READ 0x9
|
||||||
#define FWD_CMD_DISABLE 0x5
|
#define FWD_CMD_DISABLE 0x5
|
||||||
|
|
||||||
uint8_t forwardLink_data[64]; //array of forwarded bits
|
static uint8_t forwardLink_data[64]; //array of forwarded bits
|
||||||
uint8_t *forward_ptr; //ptr for forward message preparation
|
static uint8_t *forward_ptr; //ptr for forward message preparation
|
||||||
uint8_t fwd_bit_sz; //forwardlink bit counter
|
static uint8_t fwd_bit_sz; //forwardlink bit counter
|
||||||
uint8_t *fwd_write_ptr; //forwardlink bit pointer
|
static uint8_t *fwd_write_ptr; //forwardlink bit pointer
|
||||||
|
|
||||||
//====================================================================
|
//====================================================================
|
||||||
// prepares command bits
|
// prepares command bits
|
||||||
|
|
|
@ -15,10 +15,6 @@
|
||||||
|
|
||||||
#include "pm3_cmd.h" // struct
|
#include "pm3_cmd.h" // struct
|
||||||
|
|
||||||
extern uint8_t decimation;
|
|
||||||
extern uint8_t bits_per_sample ;
|
|
||||||
extern bool averaging;
|
|
||||||
|
|
||||||
void AcquireRawAdcSamples125k(int divisor);
|
void AcquireRawAdcSamples125k(int divisor);
|
||||||
void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint32_t period_1, uint8_t *command);
|
void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint32_t period_1, uint8_t *command);
|
||||||
void ReadTItag(void);
|
void ReadTItag(void);
|
||||||
|
@ -39,13 +35,17 @@ void CmdASKsimTAG(uint8_t encoding, uint8_t invert, uint8_t separator, uint8_t c
|
||||||
void CmdPSKsimTAG(uint8_t carrier, uint8_t invert, uint8_t clk, uint16_t size, uint8_t *bits, bool ledcontrol);
|
void CmdPSKsimTAG(uint8_t carrier, uint8_t invert, uint8_t clk, uint16_t size, uint8_t *bits, bool ledcontrol);
|
||||||
void CmdNRZsimTAG(uint8_t invert, uint8_t separator, uint8_t clk, uint16_t size, uint8_t *bits, bool ledcontrol);
|
void CmdNRZsimTAG(uint8_t invert, uint8_t separator, uint8_t clk, uint16_t size, uint8_t *bits, bool ledcontrol);
|
||||||
|
|
||||||
void CmdHIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol);
|
int lf_hid_watch(int findone, uint32_t *high, uint32_t *low);
|
||||||
void CmdAWIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol); // Realtime demodulation mode for AWID26
|
int lf_awid_watch(int findone, uint32_t *high, uint32_t *low); // Realtime demodulation mode for AWID26
|
||||||
void CmdEM410xdemod(int findone, uint32_t *high, uint64_t *low, int ledcontrol);
|
int lf_em410x_watch(int findone, uint32_t *high, uint64_t *low);
|
||||||
void CmdIOdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol);
|
int lf_io_watch(int findone, uint32_t *high, uint32_t *low);
|
||||||
|
|
||||||
void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT); // Clone an HID card to T5557/T5567
|
void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT); // Clone an HID card to T5557/T5567
|
||||||
|
|
||||||
void CopyVikingtoT55xx(uint8_t *blocks, uint8_t Q5);
|
void CopyVikingtoT55xx(uint8_t *blocks, uint8_t Q5);
|
||||||
void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo);
|
|
||||||
|
int copy_em410x_to_t55xx(uint8_t card, uint8_t clock, uint32_t id_hi, uint32_t id_lo);
|
||||||
|
|
||||||
void T55xxResetRead(uint8_t flags);
|
void T55xxResetRead(uint8_t flags);
|
||||||
//id T55xxWriteBlock(uint32_t data, uint8_t blockno, uint32_t pwd, uint8_t flags);
|
//id T55xxWriteBlock(uint32_t data, uint8_t blockno, uint32_t pwd, uint8_t flags);
|
||||||
void T55xxWriteBlock(uint8_t *data);
|
void T55xxWriteBlock(uint8_t *data);
|
||||||
|
|
|
@ -27,12 +27,12 @@ Default LF config is set to:
|
||||||
samples_to_skip = 0
|
samples_to_skip = 0
|
||||||
verbose = YES
|
verbose = YES
|
||||||
*/
|
*/
|
||||||
sample_config config = { 1, 8, 1, LF_DIVISOR_125, 0, 0, 1} ;
|
static sample_config config = { 1, 8, 1, LF_DIVISOR_125, 0, 0, 1} ;
|
||||||
|
|
||||||
void printConfig(void) {
|
void printConfig(void) {
|
||||||
uint32_t d = config.divisor;
|
uint32_t d = config.divisor;
|
||||||
DbpString(_BLUE_("LF Sampling config"));
|
DbpString(_CYAN_("LF Sampling config"));
|
||||||
Dbprintf(" [q] divisor.............%d ( "_GREEN_("%d.%02d kHz")")", d, 12000 / (d + 1), ((1200000 + (d + 1) / 2) / (d + 1)) - ((12000 / (d + 1)) * 100));
|
Dbprintf(" [q] divisor.............%d ( "_GREEN_("%d.%02d kHz")" )", d, 12000 / (d + 1), ((1200000 + (d + 1) / 2) / (d + 1)) - ((12000 / (d + 1)) * 100));
|
||||||
Dbprintf(" [b] bits per sample.....%d", config.bits_per_sample);
|
Dbprintf(" [b] bits per sample.....%d", config.bits_per_sample);
|
||||||
Dbprintf(" [d] decimation..........%d", config.decimation);
|
Dbprintf(" [d] decimation..........%d", config.decimation);
|
||||||
Dbprintf(" [a] averaging...........%s", (config.averaging) ? "Yes" : "No");
|
Dbprintf(" [a] averaging...........%s", (config.averaging) ? "Yes" : "No");
|
||||||
|
@ -100,10 +100,10 @@ static void pushBit(BitstreamOut *stream, uint8_t bit) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Holds bit packed struct of samples.
|
// Holds bit packed struct of samples.
|
||||||
BitstreamOut data = {0, 0, 0};
|
static BitstreamOut data = {0, 0, 0};
|
||||||
|
|
||||||
// internal struct to keep track of samples gathered
|
// internal struct to keep track of samples gathered
|
||||||
sampling_t samples = {0, 0, 0, 0};
|
static sampling_t samples = {0, 0, 0, 0};
|
||||||
|
|
||||||
void initSampleBuffer(uint32_t *sample_size) {
|
void initSampleBuffer(uint32_t *sample_size) {
|
||||||
initSampleBufferEx(sample_size, false);
|
initSampleBufferEx(sample_size, false);
|
||||||
|
@ -132,6 +132,8 @@ void initSampleBufferEx(uint32_t *sample_size, bool use_malloc) {
|
||||||
} else {
|
} else {
|
||||||
if (*sample_size == 0) {
|
if (*sample_size == 0) {
|
||||||
*sample_size = BigBuf_max_traceLen();
|
*sample_size = BigBuf_max_traceLen();
|
||||||
|
} else {
|
||||||
|
*sample_size = MIN(*sample_size, BigBuf_max_traceLen());
|
||||||
}
|
}
|
||||||
data.buffer = BigBuf_get_addr();
|
data.buffer = BigBuf_get_addr();
|
||||||
}
|
}
|
||||||
|
@ -256,11 +258,11 @@ uint32_t DoAcquisition(uint8_t decimation, uint8_t bits_per_sample, bool avg, in
|
||||||
uint32_t cancel_counter = 0;
|
uint32_t cancel_counter = 0;
|
||||||
int16_t checked = 0;
|
int16_t checked = 0;
|
||||||
|
|
||||||
while (!BUTTON_PRESS()) {
|
while (BUTTON_PRESS() == false) {
|
||||||
|
|
||||||
// only every 1000th times, in order to save time when collecting samples.
|
// only every 1000th times, in order to save time when collecting samples.
|
||||||
// interruptible only when logging not yet triggered
|
// interruptible only when logging not yet triggered
|
||||||
if ((checked == 1000) && (trigger_threshold > 0)) {
|
if ((checked == 2000) && (trigger_threshold > 0)) {
|
||||||
if (data_available()) {
|
if (data_available()) {
|
||||||
checked = -1;
|
checked = -1;
|
||||||
break;
|
break;
|
||||||
|
@ -273,7 +275,6 @@ uint32_t DoAcquisition(uint8_t decimation, uint8_t bits_per_sample, bool avg, in
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
|
|
||||||
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
|
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
|
||||||
// AT91C_BASE_SSC->SSC_THR = 0x43;
|
|
||||||
LED_D_ON();
|
LED_D_ON();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1392,7 +1392,7 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da
|
||||||
|
|
||||||
// limit size of availlable for keys in bigbuff
|
// limit size of availlable for keys in bigbuff
|
||||||
// a key is 6bytes
|
// a key is 6bytes
|
||||||
uint16_t key_mem_available = MIN(BIGBUF_SIZE, keyCount * 6);
|
uint16_t key_mem_available = MIN(BigBuf_get_size(), keyCount * 6);
|
||||||
|
|
||||||
keyCount = key_mem_available / 6;
|
keyCount = key_mem_available / 6;
|
||||||
|
|
||||||
|
@ -1940,7 +1940,7 @@ int MifareECardLoad(uint8_t sectorcnt, uint8_t keytype) {
|
||||||
clear_trace();
|
clear_trace();
|
||||||
set_tracing(true);
|
set_tracing(true);
|
||||||
|
|
||||||
int retval;
|
int retval = PM3_SUCCESS;
|
||||||
|
|
||||||
if (!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) {
|
if (!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) {
|
||||||
retval = PM3_ESOFT;
|
retval = PM3_ESOFT;
|
||||||
|
@ -1952,8 +1952,9 @@ int MifareECardLoad(uint8_t sectorcnt, uint8_t keytype) {
|
||||||
uint64_t ui64Key = emlGetKey(sectorNo, keytype);
|
uint64_t ui64Key = emlGetKey(sectorNo, keytype);
|
||||||
if (sectorNo == 0) {
|
if (sectorNo == 0) {
|
||||||
if (mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keytype, ui64Key, AUTH_FIRST)) {
|
if (mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keytype, ui64Key, AUTH_FIRST)) {
|
||||||
|
retval = PM3_ESOFT;
|
||||||
if (DBGLEVEL > DBG_ERROR) Dbprintf("Sector[%2d]. Auth error", sectorNo);
|
if (DBGLEVEL > DBG_ERROR) Dbprintf("Sector[%2d]. Auth error", sectorNo);
|
||||||
break;
|
goto out;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keytype, ui64Key, AUTH_NESTED)) {
|
if (mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keytype, ui64Key, AUTH_NESTED)) {
|
||||||
|
@ -1979,10 +1980,8 @@ int MifareECardLoad(uint8_t sectorcnt, uint8_t keytype) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mifare_classic_halt(pcs, cuid)) {
|
int res = mifare_classic_halt(pcs, cuid);
|
||||||
if (DBGLEVEL > DBG_ERROR)
|
(void)res;
|
||||||
Dbprintf("Halt error");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DBGLEVEL >= DBG_INFO) DbpString("Emulator fill sectors finished");
|
if (DBGLEVEL >= DBG_INFO) DbpString("Emulator fill sectors finished");
|
||||||
|
|
||||||
|
@ -2008,9 +2007,9 @@ out:
|
||||||
// bit 6 - wipe tag.
|
// bit 6 - wipe tag.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// magic uid card generation 1 commands
|
// magic uid card generation 1 commands
|
||||||
uint8_t wupC1[] = { MIFARE_MAGICWUPC1 };
|
static uint8_t wupC1[] = { MIFARE_MAGICWUPC1 };
|
||||||
uint8_t wupC2[] = { MIFARE_MAGICWUPC2 };
|
static uint8_t wupC2[] = { MIFARE_MAGICWUPC2 };
|
||||||
uint8_t wipeC[] = { MIFARE_MAGICWIPEC };
|
static uint8_t wipeC[] = { MIFARE_MAGICWIPEC };
|
||||||
|
|
||||||
void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain) {
|
void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain) {
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
#define RECEIVE_SIZE 64
|
#define RECEIVE_SIZE 64
|
||||||
|
|
||||||
// the block number for the ISO14443-4 PCB
|
// the block number for the ISO14443-4 PCB
|
||||||
uint8_t pcb_blocknum = 0;
|
static uint8_t pcb_blocknum = 0;
|
||||||
// Deselect card by sending a s-block. the crc is precalced for speed
|
// Deselect card by sending a s-block. the crc is precalced for speed
|
||||||
static uint8_t deselect_cmd[] = {0xc2, 0xe0, 0xb4};
|
static uint8_t deselect_cmd[] = {0xc2, 0xe0, 0xb4};
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ static uint8_t deselect_cmd[] = {0xc2, 0xe0, 0xb4};
|
||||||
/* PCB CID CMD PAYLOAD */
|
/* PCB CID CMD PAYLOAD */
|
||||||
//static uint8_t __res[MAX_FRAME_SIZE];
|
//static uint8_t __res[MAX_FRAME_SIZE];
|
||||||
|
|
||||||
struct desfire_key skey = {0};
|
static struct desfire_key skey = {0};
|
||||||
static desfirekey_t sessionkey = &skey;
|
static desfirekey_t sessionkey = &skey;
|
||||||
|
|
||||||
bool InitDesfireCard(void) {
|
bool InitDesfireCard(void) {
|
||||||
|
|
|
@ -539,9 +539,9 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1
|
||||||
if (cardSTATE == MFEMUL_NOFIELD) {
|
if (cardSTATE == MFEMUL_NOFIELD) {
|
||||||
|
|
||||||
#if defined RDV4
|
#if defined RDV4
|
||||||
vHf = (MAX_ADC_HF_VOLTAGE_RDV40 * AvgAdc(ADC_CHAN_HF_RDV40)) >> 10;
|
vHf = (MAX_ADC_HF_VOLTAGE_RDV40 * SumAdc(ADC_CHAN_HF_RDV40, 32)) >> 15;
|
||||||
#else
|
#else
|
||||||
vHf = (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10;
|
vHf = (MAX_ADC_HF_VOLTAGE * SumAdc(ADC_CHAN_HF, 32)) >> 15;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (vHf > MF_MINFIELDV) {
|
if (vHf > MF_MINFIELDV) {
|
||||||
|
|
|
@ -127,7 +127,7 @@ typedef struct {
|
||||||
|
|
||||||
|
|
||||||
// internal buffer output
|
// internal buffer output
|
||||||
static inline void _out_buffer(char character, void *buffer, size_t idx, size_t maxlen) {
|
static void _out_buffer(char character, void *buffer, size_t idx, size_t maxlen) {
|
||||||
if (idx < maxlen) {
|
if (idx < maxlen) {
|
||||||
((char *)buffer)[idx] = character;
|
((char *)buffer)[idx] = character;
|
||||||
}
|
}
|
||||||
|
@ -135,7 +135,7 @@ static inline void _out_buffer(char character, void *buffer, size_t idx, size_t
|
||||||
|
|
||||||
|
|
||||||
// internal null output
|
// internal null output
|
||||||
static inline void _out_null(char character, void *buffer, size_t idx, size_t maxlen) {
|
static void _out_null(char character, void *buffer, size_t idx, size_t maxlen) {
|
||||||
(void)character;
|
(void)character;
|
||||||
(void)buffer;
|
(void)buffer;
|
||||||
(void)idx;
|
(void)idx;
|
||||||
|
@ -144,7 +144,7 @@ static inline void _out_null(char character, void *buffer, size_t idx, size_t ma
|
||||||
|
|
||||||
|
|
||||||
// internal _putchar wrapper
|
// internal _putchar wrapper
|
||||||
static inline void _out_char(char character, void *buffer, size_t idx, size_t maxlen) {
|
static void _out_char(char character, void *buffer, size_t idx, size_t maxlen) {
|
||||||
(void)buffer;
|
(void)buffer;
|
||||||
(void)idx;
|
(void)idx;
|
||||||
(void)maxlen;
|
(void)maxlen;
|
||||||
|
@ -155,7 +155,7 @@ static inline void _out_char(char character, void *buffer, size_t idx, size_t ma
|
||||||
|
|
||||||
|
|
||||||
// internal output function wrapper
|
// internal output function wrapper
|
||||||
static inline void _out_fct(char character, void *buffer, size_t idx, size_t maxlen) {
|
static void _out_fct(char character, void *buffer, size_t idx, size_t maxlen) {
|
||||||
(void)idx;
|
(void)idx;
|
||||||
(void)maxlen;
|
(void)maxlen;
|
||||||
if (character) {
|
if (character) {
|
||||||
|
@ -167,7 +167,7 @@ static inline void _out_fct(char character, void *buffer, size_t idx, size_t max
|
||||||
|
|
||||||
// internal secure strlen
|
// internal secure strlen
|
||||||
// \return The length of the string (excluding the terminating 0) limited by 'maxsize'
|
// \return The length of the string (excluding the terminating 0) limited by 'maxsize'
|
||||||
static inline unsigned int _strnlen_s(const char *str, size_t maxsize) {
|
static unsigned int _strnlen_s(const char *str, size_t maxsize) {
|
||||||
const char *s;
|
const char *s;
|
||||||
for (s = str; *s && maxsize--; ++s);
|
for (s = str; *s && maxsize--; ++s);
|
||||||
return (unsigned int)(s - str);
|
return (unsigned int)(s - str);
|
||||||
|
@ -176,7 +176,7 @@ static inline unsigned int _strnlen_s(const char *str, size_t maxsize) {
|
||||||
|
|
||||||
// internal test if char is a digit (0-9)
|
// internal test if char is a digit (0-9)
|
||||||
// \return true if char is a digit
|
// \return true if char is a digit
|
||||||
static inline bool _is_digit(char ch) {
|
static bool _is_digit(char ch) {
|
||||||
return (ch >= '0') && (ch <= '9');
|
return (ch >= '0') && (ch <= '9');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ typedef int ssize_t;
|
||||||
|
|
||||||
#define NBBY 8 /* number of bits in a byte */
|
#define NBBY 8 /* number of bits in a byte */
|
||||||
|
|
||||||
char const hex2ascii_data[] = "0123456789abcdefghijklmnopqrstuvwxyz";
|
static char const hex2ascii_data[] = "0123456789abcdefghijklmnopqrstuvwxyz";
|
||||||
#define hex2ascii(hex) (hex2ascii_data[hex])
|
#define hex2ascii(hex) (hex2ascii_data[hex])
|
||||||
#define toupper(c) ((c) - 0x20 * (((c) >= 'a') && ((c) <= 'z')))
|
#define toupper(c) ((c) - 0x20 * (((c) >= 'a') && ((c) <= 'z')))
|
||||||
|
|
||||||
|
|
|
@ -536,13 +536,13 @@ int rdv40_spiffs_read_as_filetype(char *filename, uint8_t *dst, uint32_t size, R
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
///////// MISC HIGH LEVEL FUNCTIONS ////////////////////////////////////////////
|
///////// MISC HIGH LEVEL FUNCTIONS ////////////////////////////////////////////
|
||||||
#define SPIFFS_BANNER DbpString(_BLUE_("Flash Memory FileSystem tree (SPIFFS)"));
|
#define SPIFFS_BANNER DbpString(_CYAN_("Flash Memory FileSystem tree (SPIFFS)"));
|
||||||
|
|
||||||
void rdv40_spiffs_safe_print_fsinfo(void) {
|
void rdv40_spiffs_safe_print_fsinfo(void) {
|
||||||
rdv40_spiffs_fsinfo fsinfo;
|
rdv40_spiffs_fsinfo fsinfo;
|
||||||
rdv40_spiffs_getfsinfo(&fsinfo, RDV40_SPIFFS_SAFETY_SAFE);
|
rdv40_spiffs_getfsinfo(&fsinfo, RDV40_SPIFFS_SAFETY_SAFE);
|
||||||
|
|
||||||
DbpString(_BLUE_("Flash Memory FileSystem Info (SPIFFS)"));
|
DbpString(_CYAN_("Flash Memory FileSystem Info (SPIFFS)"));
|
||||||
|
|
||||||
|
|
||||||
Dbprintf(" Logical Block Size........." _YELLOW_("%d")" bytes", fsinfo.blockSize);
|
Dbprintf(" Logical Block Size........." _YELLOW_("%d")" bytes", fsinfo.blockSize);
|
||||||
|
@ -570,7 +570,7 @@ void rdv40_spiffs_safe_print_fsinfo(void) {
|
||||||
void rdv40_spiffs_safe_print_tree(uint8_t banner) {
|
void rdv40_spiffs_safe_print_tree(uint8_t banner) {
|
||||||
|
|
||||||
if (banner) {
|
if (banner) {
|
||||||
DbpString(_BLUE_("Flash Memory FileSystem tree (SPIFFS)"));
|
DbpString(_CYAN_("Flash Memory FileSystem tree (SPIFFS)"));
|
||||||
Dbprintf("-------------------------------------");
|
Dbprintf("-------------------------------------");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,13 +39,12 @@ s32_t SPIFFS_format(spiffs *fs) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32_t res;
|
|
||||||
SPIFFS_LOCK(fs);
|
SPIFFS_LOCK(fs);
|
||||||
|
|
||||||
spiffs_block_ix bix = 0;
|
spiffs_block_ix bix = 0;
|
||||||
while (bix < fs->block_count) {
|
while (bix < fs->block_count) {
|
||||||
fs->max_erase_count = 0;
|
fs->max_erase_count = 0;
|
||||||
res = spiffs_erase_block(fs, bix);
|
s32_t res = spiffs_erase_block(fs, bix);
|
||||||
if (res != SPIFFS_OK) {
|
if (res != SPIFFS_OK) {
|
||||||
res = SPIFFS_ERR_ERASE_FAIL;
|
res = SPIFFS_ERR_ERASE_FAIL;
|
||||||
}
|
}
|
||||||
|
@ -1121,11 +1120,11 @@ s32_t SPIFFS_check(spiffs *fs) {
|
||||||
SPIFFS_LOCK(fs);
|
SPIFFS_LOCK(fs);
|
||||||
|
|
||||||
res = spiffs_lookup_consistency_check(fs, 0);
|
res = spiffs_lookup_consistency_check(fs, 0);
|
||||||
|
(void)res;
|
||||||
res = spiffs_object_index_consistency_check(fs);
|
res = spiffs_object_index_consistency_check(fs);
|
||||||
|
(void)res;
|
||||||
res = spiffs_page_consistency_check(fs);
|
res = spiffs_page_consistency_check(fs);
|
||||||
|
(void)res;
|
||||||
res = spiffs_obj_lu_scan(fs);
|
res = spiffs_obj_lu_scan(fs);
|
||||||
|
|
||||||
SPIFFS_UNLOCK(fs);
|
SPIFFS_UNLOCK(fs);
|
||||||
|
|
|
@ -14,70 +14,40 @@
|
||||||
|
|
||||||
#include "proxmark3_arm.h"
|
#include "proxmark3_arm.h"
|
||||||
#include "appmain.h"
|
#include "appmain.h"
|
||||||
#include "zlib.h"
|
#include "lz4.h"
|
||||||
#include "BigBuf.h"
|
#include "BigBuf.h"
|
||||||
|
#include "string.h"
|
||||||
|
|
||||||
static uint8_t *next_free_memory;
|
static uint8_t *next_free_memory;
|
||||||
extern struct common_area common_area;
|
extern struct common_area common_area;
|
||||||
extern char __data_src_start__, __data_start__, __data_end__, __bss_start__, __bss_end__;
|
extern char __data_src_start__, __data_start__, __data_end__, __bss_start__, __bss_end__;
|
||||||
|
|
||||||
static voidpf inflate_malloc(voidpf opaque, uInt items, uInt size) {
|
|
||||||
uint8_t *allocated_memory;
|
|
||||||
|
|
||||||
allocated_memory = next_free_memory;
|
|
||||||
next_free_memory += items * size;
|
|
||||||
return allocated_memory;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void inflate_free(voidpf opaque, voidpf address) {
|
|
||||||
// nothing to do
|
|
||||||
}
|
|
||||||
|
|
||||||
static void uncompress_data_section(void) {
|
static void uncompress_data_section(void) {
|
||||||
z_stream data_section;
|
|
||||||
|
|
||||||
next_free_memory = BigBuf_get_addr();
|
next_free_memory = BigBuf_get_addr();
|
||||||
|
int avail_in;
|
||||||
|
memcpy(&avail_in, &__data_start__, sizeof(int));
|
||||||
|
int avail_out = &__data_end__ - &__data_start__; // uncompressed size. Correct.
|
||||||
|
// uncompress data segment to RAM
|
||||||
|
uintptr_t p = (uintptr_t)&__data_src_start__;
|
||||||
|
int res = LZ4_decompress_safe((char *)p + 4, &__data_start__, avail_in, avail_out);
|
||||||
|
|
||||||
// initialize zstream structure
|
|
||||||
data_section.next_in = (uint8_t *) &__data_src_start__;
|
|
||||||
data_section.avail_in = &__data_end__ - &__data_start__; // uncompressed size. Wrong but doesn't matter.
|
|
||||||
data_section.next_out = (uint8_t *) &__data_start__;
|
|
||||||
data_section.avail_out = &__data_end__ - &__data_start__; // uncompressed size. Correct.
|
|
||||||
data_section.zalloc = &inflate_malloc;
|
|
||||||
data_section.zfree = &inflate_free;
|
|
||||||
data_section.opaque = NULL;
|
|
||||||
|
|
||||||
// initialize zlib for inflate
|
|
||||||
int res = inflateInit2(&data_section, 15);
|
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// uncompress data segment to RAM
|
|
||||||
inflate(&data_section, Z_FINISH);
|
|
||||||
|
|
||||||
// save the size of the compressed data section
|
// save the size of the compressed data section
|
||||||
common_area.arg1 = data_section.total_in;
|
common_area.arg1 = res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void __attribute__((section(".startos"))) Vector(void);
|
void __attribute__((section(".startos"))) Vector(void);
|
||||||
void Vector(void) {
|
void Vector(void) {
|
||||||
/* Stack should have been set up by the bootloader */
|
/* Stack should have been set up by the bootloader */
|
||||||
// char *src;
|
|
||||||
char *dst, *end;
|
|
||||||
|
|
||||||
uncompress_data_section();
|
uncompress_data_section();
|
||||||
|
|
||||||
/* Set up (that is: clear) BSS. */
|
/* Set up (that is: clear) BSS. */
|
||||||
dst = &__bss_start__;
|
char *dst = &__bss_start__;
|
||||||
end = &__bss_end__;
|
char *end = &__bss_end__;
|
||||||
while (dst < end) *dst++ = 0;
|
while (dst < end) *dst++ = 0;
|
||||||
|
|
||||||
// Set up data segment: Copy from flash to ram
|
|
||||||
// src = &__data_src_start__;
|
|
||||||
// dst = &__data_start__;
|
|
||||||
// end = &__data_end__;
|
|
||||||
// while(dst < end) *dst++ = *src++;
|
|
||||||
|
|
||||||
AppMain();
|
AppMain();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -20,6 +20,21 @@ void *memcpy(void *dest, const void *src, int len) {
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *memmove(void *dest, const void *src, size_t len) {
|
||||||
|
char *d = dest;
|
||||||
|
const char *s = src;
|
||||||
|
if (d < s)
|
||||||
|
while (len--)
|
||||||
|
*d++ = *s++;
|
||||||
|
else {
|
||||||
|
char *lasts = (char *)s + (len - 1);
|
||||||
|
char *lastd = d + (len - 1);
|
||||||
|
while (len--)
|
||||||
|
*lastd-- = *lasts--;
|
||||||
|
}
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
void *memset(void *dest, int c, int len) {
|
void *memset(void *dest, int c, int len) {
|
||||||
uint8_t *d = dest;
|
uint8_t *d = dest;
|
||||||
while ((len--) > 0) {
|
while ((len--) > 0) {
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
int strlen(const char *str);
|
int strlen(const char *str);
|
||||||
void *memcpy(void *dest, const void *src, int len);
|
void *memcpy(void *dest, const void *src, int len);
|
||||||
|
void *memmove(void *dest, const void *src, size_t len);
|
||||||
void *memset(void *dest, int c, int len);
|
void *memset(void *dest, int c, int len);
|
||||||
int memcmp(const void *av, const void *bv, int len);
|
int memcmp(const void *av, const void *bv, int len);
|
||||||
void memxor(uint8_t *dest, uint8_t *src, size_t len);
|
void memxor(uint8_t *dest, uint8_t *src, size_t len);
|
||||||
|
|
|
@ -49,7 +49,7 @@ void ReadThinFilm(void) {
|
||||||
#define SEC_D 0xf0
|
#define SEC_D 0xf0
|
||||||
#define SEC_E 0x0f
|
#define SEC_E 0x0f
|
||||||
#define SEC_F 0x00
|
#define SEC_F 0x00
|
||||||
uint16_t FpgaSendQueueDelay;
|
static uint16_t FpgaSendQueueDelay;
|
||||||
|
|
||||||
static uint16_t ReadReaderField(void) {
|
static uint16_t ReadReaderField(void) {
|
||||||
#if defined RDV4
|
#if defined RDV4
|
||||||
|
|
|
@ -15,8 +15,8 @@ volatile AT91PS_USART pUS1 = AT91C_BASE_US1;
|
||||||
volatile AT91PS_PIO pPIO = AT91C_BASE_PIOA;
|
volatile AT91PS_PIO pPIO = AT91C_BASE_PIOA;
|
||||||
volatile AT91PS_PDC pPDC = AT91C_BASE_PDC_US1;
|
volatile AT91PS_PDC pPDC = AT91C_BASE_PDC_US1;
|
||||||
|
|
||||||
uint32_t usart_baudrate = 0;
|
uint32_t g_usart_baudrate = 0;
|
||||||
uint8_t usart_parity = 0;
|
uint8_t g_usart_parity = 0;
|
||||||
/*
|
/*
|
||||||
void usart_close(void) {
|
void usart_close(void) {
|
||||||
// Reset the USART mode
|
// Reset the USART mode
|
||||||
|
@ -41,8 +41,8 @@ void usart_close(void) {
|
||||||
|
|
||||||
static uint8_t us_inbuf1[USART_BUFFLEN];
|
static uint8_t us_inbuf1[USART_BUFFLEN];
|
||||||
static uint8_t us_inbuf2[USART_BUFFLEN];
|
static uint8_t us_inbuf2[USART_BUFFLEN];
|
||||||
uint8_t *usart_cur_inbuf = NULL;
|
static uint8_t *usart_cur_inbuf = NULL;
|
||||||
uint16_t usart_cur_inbuf_off = 0;
|
static uint16_t usart_cur_inbuf_off = 0;
|
||||||
static uint8_t us_rxfifo[USART_FIFOLEN];
|
static uint8_t us_rxfifo[USART_FIFOLEN];
|
||||||
static size_t us_rxfifo_low = 0;
|
static size_t us_rxfifo_low = 0;
|
||||||
static size_t us_rxfifo_high = 0;
|
static size_t us_rxfifo_high = 0;
|
||||||
|
@ -166,9 +166,9 @@ inline int usart_writebuffer_sync(uint8_t *data, size_t len) {
|
||||||
void usart_init(uint32_t baudrate, uint8_t parity) {
|
void usart_init(uint32_t baudrate, uint8_t parity) {
|
||||||
|
|
||||||
if (baudrate != 0)
|
if (baudrate != 0)
|
||||||
usart_baudrate = baudrate;
|
g_usart_baudrate = baudrate;
|
||||||
if ((parity == 'N') || (parity == 'O') || (parity == 'E'))
|
if ((parity == 'N') || (parity == 'O') || (parity == 'E'))
|
||||||
usart_parity = parity;
|
g_usart_parity = parity;
|
||||||
|
|
||||||
// For a nice detailed sample, interrupt driven but still relevant.
|
// For a nice detailed sample, interrupt driven but still relevant.
|
||||||
// See https://www.sparkfun.com/datasheets/DevTools/SAM7/at91sam7%20serial%20communications.pdf
|
// See https://www.sparkfun.com/datasheets/DevTools/SAM7/at91sam7%20serial%20communications.pdf
|
||||||
|
@ -197,7 +197,7 @@ void usart_init(uint32_t baudrate, uint8_t parity) {
|
||||||
AT91C_US_NBSTOP_1_BIT | // 1 stop bit
|
AT91C_US_NBSTOP_1_BIT | // 1 stop bit
|
||||||
AT91C_US_CHMODE_NORMAL; // channel mode: normal
|
AT91C_US_CHMODE_NORMAL; // channel mode: normal
|
||||||
|
|
||||||
switch (usart_parity) {
|
switch (g_usart_parity) {
|
||||||
case 'N':
|
case 'N':
|
||||||
mode |= AT91C_US_PAR_NONE; // parity: none
|
mode |= AT91C_US_PAR_NONE; // parity: none
|
||||||
break;
|
break;
|
||||||
|
@ -227,9 +227,9 @@ void usart_init(uint32_t baudrate, uint8_t parity) {
|
||||||
// OVER = 1, -yes we are oversampling
|
// OVER = 1, -yes we are oversampling
|
||||||
// baudrate == selected clock/8/CD --> this is ours
|
// baudrate == selected clock/8/CD --> this is ours
|
||||||
//
|
//
|
||||||
uint32_t brgr = MCK / (usart_baudrate << 3);
|
uint32_t brgr = MCK / (g_usart_baudrate << 3);
|
||||||
// doing fp = round((mck / (usart_baudrate << 3) - brgr) * 8) with integers:
|
// doing fp = round((mck / (g_usart_baudrate << 3) - brgr) * 8) with integers:
|
||||||
uint32_t fp = ((16 * MCK / (usart_baudrate << 3) - 16 * brgr) + 1) / 2;
|
uint32_t fp = ((16 * MCK / (g_usart_baudrate << 3) - 16 * brgr) + 1) / 2;
|
||||||
|
|
||||||
pUS1->US_BRGR = (fp << 16) | brgr;
|
pUS1->US_BRGR = (fp << 16) | brgr;
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,8 @@
|
||||||
|
|
||||||
// Higher baudrates are pointless, only increasing overflow risk
|
// Higher baudrates are pointless, only increasing overflow risk
|
||||||
|
|
||||||
extern uint32_t usart_baudrate;
|
extern uint32_t g_usart_baudrate;
|
||||||
extern uint8_t usart_parity;
|
extern uint8_t g_usart_parity;
|
||||||
|
|
||||||
void usart_init(uint32_t baudrate, uint8_t parity);
|
void usart_init(uint32_t baudrate, uint8_t parity);
|
||||||
int usart_writebuffer_sync(uint8_t *data, size_t len);
|
int usart_writebuffer_sync(uint8_t *data, size_t len);
|
||||||
|
|
|
@ -289,40 +289,6 @@ int BUTTON_HELD(int ms) {
|
||||||
return BUTTON_ERROR;
|
return BUTTON_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Similar to FpgaGatherVersion this formats stored version information
|
|
||||||
* into a string representation. It takes a pointer to the struct version_information,
|
|
||||||
* verifies the magic properties, then stores a formatted string, prefixed by
|
|
||||||
* prefix in dst.
|
|
||||||
*/
|
|
||||||
void FormatVersionInformation(char *dst, int len, const char *prefix, void *version_information) {
|
|
||||||
struct version_information *v = (struct version_information *)version_information;
|
|
||||||
dst[0] = 0;
|
|
||||||
strncat(dst, prefix, len - 1);
|
|
||||||
if (v->magic != VERSION_INFORMATION_MAGIC) {
|
|
||||||
strncat(dst, "Missing/Invalid version information\n", len - strlen(dst) - 1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (v->versionversion != 1) {
|
|
||||||
strncat(dst, "Version information not understood\n", len - strlen(dst) - 1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!v->present) {
|
|
||||||
strncat(dst, "Version information not available\n", len - strlen(dst) - 1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
strncat(dst, v->gitversion, len - strlen(dst) - 1);
|
|
||||||
if (v->clean == 0) {
|
|
||||||
strncat(dst, "-unclean", len - strlen(dst) - 1);
|
|
||||||
} else if (v->clean == 2) {
|
|
||||||
strncat(dst, "-suspect", len - strlen(dst) - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
strncat(dst, " ", len - strlen(dst) - 1);
|
|
||||||
strncat(dst, v->buildtime, len - strlen(dst) - 1);
|
|
||||||
strncat(dst, "\n", len - strlen(dst) - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool data_available(void) {
|
bool data_available(void) {
|
||||||
#ifdef WITH_FPC_USART_HOST
|
#ifdef WITH_FPC_USART_HOST
|
||||||
return usb_poll_validate_length() || (usart_rxdata_available() > 0);
|
return usb_poll_validate_length() || (usart_rxdata_available() > 0);
|
||||||
|
|
|
@ -91,7 +91,6 @@ void SpinUp(uint32_t speed);
|
||||||
|
|
||||||
int BUTTON_CLICKED(int ms);
|
int BUTTON_CLICKED(int ms);
|
||||||
int BUTTON_HELD(int ms);
|
int BUTTON_HELD(int ms);
|
||||||
void FormatVersionInformation(char *dst, int len, const char *prefix, void *version_information);
|
|
||||||
bool data_available(void);
|
bool data_available(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -23,7 +23,7 @@ VERSIONSRC = version.c
|
||||||
# THUMBSRC :=
|
# THUMBSRC :=
|
||||||
|
|
||||||
# stdint.h provided locally until GCC 4.5 becomes C99 compliant
|
# stdint.h provided locally until GCC 4.5 becomes C99 compliant
|
||||||
APP_CFLAGS = -I. -fno-strict-aliasing -ffunction-sections -fdata-sections
|
APP_CFLAGS = -I. -ffunction-sections -fdata-sections
|
||||||
|
|
||||||
# stack-protect , no-pie reduces size on Gentoo Hardened 8.2 gcc
|
# stack-protect , no-pie reduces size on Gentoo Hardened 8.2 gcc
|
||||||
APP_CFLAGS += -fno-stack-protector -fno-pie
|
APP_CFLAGS += -fno-stack-protector -fno-pie
|
||||||
|
@ -39,7 +39,7 @@ OBJS = $(OBJDIR)/bootrom.s19
|
||||||
# version.c should be remade on every compilation
|
# version.c should be remade on every compilation
|
||||||
version.c: default_version.c
|
version.c: default_version.c
|
||||||
$(info [=] GEN $@)
|
$(info [=] GEN $@)
|
||||||
$(Q)sh ../tools/mkversion.sh > $@ || perl ../tools/mkversion.pl > $@ || $(CP) $^ $@
|
$(Q)$(SH) ../tools/mkversion.sh > $@ || $(PERL) ../tools/mkversion.pl > $@ || $(CP) $< $@
|
||||||
|
|
||||||
all: showinfo $(OBJS)
|
all: showinfo $(OBJS)
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ tarbin: $(OBJS)
|
||||||
|
|
||||||
$(OBJDIR)/bootrom.elf: $(VERSIONOBJ) $(ASMOBJ) $(ARMOBJ) $(THUMBOBJ)
|
$(OBJDIR)/bootrom.elf: $(VERSIONOBJ) $(ASMOBJ) $(ARMOBJ) $(THUMBOBJ)
|
||||||
$(info [=] LD $@)
|
$(info [=] LD $@)
|
||||||
$(Q)$(CC) $(LDFLAGS) -Wl,-T,ldscript-flash,-Map,$(patsubst %.elf,%.map,$@) -o $@ $^ $(LIBS)
|
$(Q)$(CC) $(CROSS_LDFLAGS) -Wl,-T,ldscript-flash,-Map,$(patsubst %.elf,%.map,$@) -o $@ $^ $(LIBS)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(Q)$(RM) $(OBJDIR)$(PATHSEP)*.o
|
$(Q)$(RM) $(OBJDIR)$(PATHSEP)*.o
|
||||||
|
|
|
@ -38,12 +38,8 @@ static int reply_old(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int result = PM3_EUNDEF;
|
|
||||||
// Send frame and make sure all bytes are transmitted
|
// Send frame and make sure all bytes are transmitted
|
||||||
|
return usb_write((uint8_t *)&txcmd, sizeof(PacketResponseOLD));
|
||||||
result = usb_write((uint8_t *)&txcmd, sizeof(PacketResponseOLD));
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
|
@ -80,7 +76,7 @@ static void Fatal(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void UsbPacketReceived(uint8_t *packet) {
|
static void UsbPacketReceived(uint8_t *packet) {
|
||||||
int i, dont_ack = 0;
|
int dont_ack = 0;
|
||||||
PacketCommandOLD *c = (PacketCommandOLD *)packet;
|
PacketCommandOLD *c = (PacketCommandOLD *)packet;
|
||||||
|
|
||||||
//if ( len != sizeof(PacketCommandOLD`)) Fatal();
|
//if ( len != sizeof(PacketCommandOLD`)) Fatal();
|
||||||
|
@ -128,7 +124,7 @@ static void UsbPacketReceived(uint8_t *packet) {
|
||||||
// We need to offset the writes or it will not fill the correct bank write buffer.
|
// We need to offset the writes or it will not fill the correct bank write buffer.
|
||||||
offset = (AT91C_IFLASH_NB_OF_PAGES / 2) * AT91C_IFLASH_PAGE_SIZE / sizeof(uint32_t);
|
offset = (AT91C_IFLASH_NB_OF_PAGES / 2) * AT91C_IFLASH_PAGE_SIZE / sizeof(uint32_t);
|
||||||
}
|
}
|
||||||
for (i = 0 + (64 * j); i < 64 + (64 * j); i++) {
|
for (int i = 0 + (64 * j); i < 64 + (64 * j); i++) {
|
||||||
_flash_start[offset + i] = c->d.asDwords[i];
|
_flash_start[offset + i] = c->d.asDwords[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,228 +1,454 @@
|
||||||
|
# Usage:
|
||||||
|
# mkdir build
|
||||||
|
# cd build
|
||||||
|
# cmake .. (see below for options)
|
||||||
|
# make (VERBOSE=1 if needed)
|
||||||
|
#
|
||||||
# MINGW:
|
# MINGW:
|
||||||
# On ProxSpace 3.4:
|
# On ProxSpace 3.4:
|
||||||
# cmake -G"MSYS Makefiles" ..
|
# cmake -G"MSYS Makefiles" ..
|
||||||
# On Proxspace 3.3 or less, you need to install cmake:
|
# On Proxspace 3.3 or less, you need to install cmake:
|
||||||
# pacman -S mingw-w64-x86_64-cmake
|
# pacman -S mingw-w64-x86_64-cmake
|
||||||
# /mingw64/bin/cmake -G"MSYS Makefiles" ..
|
# /mingw64/bin/cmake -G"MSYS Makefiles" ..
|
||||||
|
#
|
||||||
|
# Android cross-compilation: (ANDROID_ABI=arm64-v8a for a 64b version)
|
||||||
|
# cmake \
|
||||||
|
# -DCMAKE_TOOLCHAIN_FILE=<path-to-your-android-ndk>/build/cmake/android.toolchain.cmake \
|
||||||
|
# -DANDROID_ABI=armeabi-v7a \
|
||||||
|
# -DANDROID_NATIVE_API_LEVEL=android-19 \
|
||||||
|
# -DSKIPBT=1 -DSKIPPYTHON=1 -DSKIPPTHREAD=1 ..
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 3.10)
|
cmake_minimum_required(VERSION 3.10)
|
||||||
project(proxmark3)
|
project(proxmark3)
|
||||||
|
SET (PM3_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/..)
|
||||||
|
|
||||||
if(CMAKE_VERSION VERSION_LESS "3.7.0")
|
if(CMAKE_VERSION VERSION_LESS "3.7.0")
|
||||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(APPLE AND EXISTS /usr/local/opt/qt5)
|
|
||||||
# Homebrew installs Qt5 (up to at least 5.11.0) in
|
|
||||||
# /usr/local/qt5. Ensure that it can be found by CMake
|
|
||||||
# since it is not in the default /usr/local prefix.
|
|
||||||
# Add it to PATHS so that it doesn't override the
|
|
||||||
# CMAKE_PREFIX_PATH environment variable.
|
|
||||||
# QT_FIND_PACKAGE_OPTIONS should be passed to find_package,
|
|
||||||
# e.g. find_package(Qt5Core ${QT_FIND_PACKAGE_OPTIONS})
|
|
||||||
list(APPEND QT_FIND_PACKAGE_OPTIONS PATHS /usr/local/opt/qt5)
|
|
||||||
endif()
|
|
||||||
set(QT_PACKAGELIST
|
|
||||||
Qt5Core
|
|
||||||
Qt5Widgets
|
|
||||||
Qt5Gui
|
|
||||||
)
|
|
||||||
set(Qt5_FOUND ON)
|
|
||||||
foreach(_qt_package IN LISTS QT_PACKAGELIST)
|
|
||||||
find_package(${_qt_package} QUIET ${QT_FIND_PACKAGE_OPTIONS})
|
|
||||||
if(NOT ${_qt_package}_FOUND)
|
|
||||||
set(Qt5_FOUND OFF)
|
|
||||||
endif(NOT ${_qt_package}_FOUND)
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
find_package(PkgConfig)
|
find_package(PkgConfig)
|
||||||
pkg_search_module(BLUEZ QUIET bluez)
|
|
||||||
|
|
||||||
SET (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
if (NOT SKIPQT EQUAL 1)
|
||||||
|
if(APPLE AND EXISTS /usr/local/opt/qt5)
|
||||||
|
# Homebrew installs Qt5 (up to at least 5.11.0) in
|
||||||
|
# /usr/local/qt5. Ensure that it can be found by CMake
|
||||||
|
# since it is not in the default /usr/local prefix.
|
||||||
|
# Add it to PATHS so that it doesn't override the
|
||||||
|
# CMAKE_PREFIX_PATH environment variable.
|
||||||
|
# QT_FIND_PACKAGE_OPTIONS should be passed to find_package,
|
||||||
|
# e.g. find_package(Qt5Core ${QT_FIND_PACKAGE_OPTIONS})
|
||||||
|
list(APPEND QT_FIND_PACKAGE_OPTIONS PATHS /usr/local/opt/qt5)
|
||||||
|
endif(APPLE AND EXISTS /usr/local/opt/qt5)
|
||||||
|
set(QT_PACKAGELIST
|
||||||
|
Qt5Core
|
||||||
|
Qt5Widgets
|
||||||
|
Qt5Gui
|
||||||
|
)
|
||||||
|
set(Qt5_FOUND ON)
|
||||||
|
foreach(_qt_package IN LISTS QT_PACKAGELIST)
|
||||||
|
find_package(${_qt_package} QUIET ${QT_FIND_PACKAGE_OPTIONS})
|
||||||
|
set(Qt5_LIBRARIES ${${_qt_package}_LIBRARIES} ${Qt5_LIBRARIES})
|
||||||
|
if(NOT ${_qt_package}_FOUND)
|
||||||
|
set(Qt5_FOUND OFF)
|
||||||
|
endif(NOT ${_qt_package}_FOUND)
|
||||||
|
endforeach()
|
||||||
|
endif (NOT SKIPQT EQUAL 1)
|
||||||
|
|
||||||
add_subdirectory(deps)
|
if (NOT SKIPBT EQUAL 1)
|
||||||
|
pkg_search_module(BLUEZ QUIET bluez)
|
||||||
|
endif (NOT SKIPBT EQUAL 1)
|
||||||
|
|
||||||
|
if (NOT SKIPPYTHON EQUAL 1)
|
||||||
|
pkg_search_module(PYTHON3 QUIET python3)
|
||||||
|
pkg_search_module(PYTHON3EMBED QUIET python3-embed)
|
||||||
|
endif (NOT SKIPPYTHON EQUAL 1)
|
||||||
|
|
||||||
|
# If build on android cross, we need to init source and build.
|
||||||
|
if (ANDROID)
|
||||||
|
set(CFLAGS_EXTERNAL_LIB "CFLAGS=--target=${CMAKE_C_COMPILER_TARGET} -w")
|
||||||
|
include(ExternalProject)
|
||||||
|
endif (ANDROID)
|
||||||
|
|
||||||
|
if (NOT SKIPREADLINE EQUAL 1)
|
||||||
|
if (APPLE)
|
||||||
|
find_path(READLINE_INCLUDE_DIRS readline/readline.h /usr/local/opt/readline/include /opt/local/include /opt/include /usr/local/include /usr/include NO_DEFAULT_PATH)
|
||||||
|
find_library(READLINE_LIBRARIES readline /usr/local/opt/readline/lib /opt/local/lib /opt/lib /usr/local/lib /usr/lib NO_DEFAULT_PATH)
|
||||||
|
endif (APPLE)
|
||||||
|
if (ANDROID)
|
||||||
|
ExternalProject_Add(ncurses
|
||||||
|
URL http://ftp.gnu.org/pub/gnu/ncurses/ncurses-6.0.tar.gz
|
||||||
|
PREFIX deps/ncurses
|
||||||
|
DOWNLOAD_DIR ${CMAKE_CURRENT_SOURCE_DIR}/deps/ncurses
|
||||||
|
CONFIGURE_COMMAND ./configure CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER} LD=${CMAKE_C_COMPILER} AR=${CMAKE_AR} RANLIB=${CMAKE_RANLIB} ${CFLAGS_EXTERNAL_LIB} --host=arm --disable-database --with-fallbacks=ansi-generic,ansi-mini,color_xterm,dtterm,dumb,Eterm,Eterm-256color,Eterm-88color,eterm-color,gnome,gnome-256color,guru,hurd,iTerm.app,konsole,konsole-16color,konsole-256color,konsole-base,konsole-linux,konsole-solaris,konsole-vt100,kterm,kterm-color,linux,linux-16color,linux-basic,mac,mlterm,mlterm-256color,mrxvt,mrxvt-256color,mterm,mterm-ansi,mvterm,nsterm,nsterm-16color,nsterm-256color,pty,putty,putty-256color,putty-vt100,rxvt,rxvt-16color,rxvt-256color,rxvt-88color,rxvt-basic,rxvt-color,screen,screen-16color,screen-256color,simpleterm,st-16color,st-256color,st52,st52-color,stv52,tt,tt52,unknown,vt100,vt102,vte,vte-256color,xterm,xterm-16color,xterm-256color,xterm-88color,xterm-basic,xterm-bold,xterm-color,xterm-utf8,xterm-vt220,xterm-vt52,xterm1,xtermc,xtermm --enable-termcap --without-ada --without-debug --without-dlsym --without-gpm --without-develop --without-tests --without-cxx-binding --with-termlib
|
||||||
|
BUILD_IN_SOURCE ON
|
||||||
|
BUILD_COMMAND make libs
|
||||||
|
INSTALL_COMMAND ""
|
||||||
|
LOG_DOWNLOAD ON
|
||||||
|
)
|
||||||
|
ExternalProject_Add_StepTargets(ncurses configure build install)
|
||||||
|
|
||||||
|
ExternalProject_Add(readline
|
||||||
|
URL ftp://ftp.gnu.org/gnu/readline/readline-7.0.tar.gz
|
||||||
|
PREFIX deps/readline
|
||||||
|
DOWNLOAD_DIR ${CMAKE_CURRENT_SOURCE_DIR}/deps/readline
|
||||||
|
CONFIGURE_COMMAND ./configure CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER} LD=${CMAKE_C_COMPILER} AR=${CMAKE_AR} RANLIB=${CMAKE_RANLIB} ${CFLAGS_EXTERNAL_LIB} --host=arm --enable-static
|
||||||
|
BUILD_IN_SOURCE ON
|
||||||
|
BUILD_COMMAND make
|
||||||
|
INSTALL_COMMAND ""
|
||||||
|
LOG_DOWNLOAD ON
|
||||||
|
)
|
||||||
|
ExternalProject_Add_StepTargets(readline configure build install)
|
||||||
|
set(READLINE_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR}/deps/readline/src/)
|
||||||
|
set(READLINE_LIBRARIES ${CMAKE_CURRENT_BINARY_DIR}/deps/readline/src/readline/libreadline.a ${CMAKE_CURRENT_BINARY_DIR}/deps/ncurses/src/ncurses/lib/libtinfo.a)
|
||||||
|
else (ANDROID)
|
||||||
|
find_path(READLINE_INCLUDE_DIRS readline/readline.h)
|
||||||
|
find_library(READLINE_LIBRARIES readline)
|
||||||
|
endif (ANDROID)
|
||||||
|
if (READLINE_INCLUDE_DIRS AND READLINE_LIBRARIES)
|
||||||
|
set(READLINE_FOUND ON)
|
||||||
|
endif (READLINE_INCLUDE_DIRS AND READLINE_LIBRARIES)
|
||||||
|
endif (NOT SKIPREADLINE EQUAL 1)
|
||||||
|
|
||||||
|
if (NOT SKIPJANSSONSYSTEM EQUAL 1)
|
||||||
|
pkg_check_modules(PC_JANSSON QUIET jansson)
|
||||||
|
find_path(JANSSON_INCLUDE_DIRS
|
||||||
|
NAMES jansson.h
|
||||||
|
HINTS ${PC_JANSSON_INCLUDEDIR} ${PC_JANSSON_INCLUDE_DIRS})
|
||||||
|
find_library(JANSSON_LIBRARIES
|
||||||
|
NAMES jansson libjansson
|
||||||
|
HINTS ${PC_JANSSON_LIBDIR} ${PC_JANSSON_LIBRARY_DIRS})
|
||||||
|
if (JANSSON_INCLUDE_DIRS AND JANSSON_LIBRARIES)
|
||||||
|
set(JANSSON_FOUND ON)
|
||||||
|
endif (JANSSON_INCLUDE_DIRS AND JANSSON_LIBRARIES)
|
||||||
|
endif (NOT SKIPJANSSONSYSTEM EQUAL 1)
|
||||||
|
|
||||||
|
if(ANDROID)
|
||||||
|
set(BZIP2_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/deps/bzip2/src/bzip2)
|
||||||
|
ExternalProject_Add(bzip2
|
||||||
|
GIT_REPOSITORY https://android.googlesource.com/platform/external/bzip2
|
||||||
|
GIT_TAG platform-tools-30.0.2
|
||||||
|
PREFIX deps/bzip2
|
||||||
|
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/deps/bzip2
|
||||||
|
CONFIGURE_COMMAND mkdir -p ${BZIP2_BUILD_DIR} && git archive --format tar HEAD | tar -C ${BZIP2_BUILD_DIR} -x
|
||||||
|
BUILD_IN_SOURCE ON
|
||||||
|
BUILD_COMMAND make -C ${BZIP2_BUILD_DIR} -j4 CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER} LD=${CMAKE_C_COMPILER} AR=${CMAKE_AR} RANLIB=${CMAKE_RANLIB} ${CFLAGS_EXTERNAL_LIB} libbz2.a
|
||||||
|
INSTALL_COMMAND ""
|
||||||
|
LOG_DOWNLOAD ON
|
||||||
|
)
|
||||||
|
ExternalProject_Add_StepTargets(bzip2 configure build install)
|
||||||
|
set(BZIP2_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR}/deps/bzip2/src/bzip2)
|
||||||
|
set(BZIP2_LIBRARIES ${CMAKE_CURRENT_BINARY_DIR}/deps/bzip2/src/bzip2/libbz2.a)
|
||||||
|
set(BZIP2_FOUND ON)
|
||||||
|
else()
|
||||||
|
find_package (BZip2 REQUIRED)
|
||||||
|
endif(ANDROID)
|
||||||
|
|
||||||
|
if (NOT SKIPWHEREAMISYSTEM EQUAL 1)
|
||||||
|
find_path(WHEREAMI_INCLUDE_DIRS whereami.h)
|
||||||
|
find_library(WHEREAMI_LIBRARIES whereami)
|
||||||
|
if (WHEREAMI_INCLUDE_DIRS AND WHEREAMI_LIBRARIES)
|
||||||
|
set(WHEREAMI_FOUND ON)
|
||||||
|
endif (WHEREAMI_INCLUDE_DIRS AND WHEREAMI_LIBRARIES)
|
||||||
|
endif (NOT SKIPWHEREAMISYSTEM EQUAL 1)
|
||||||
|
|
||||||
|
add_subdirectory(${PM3_ROOT}/client/deps deps)
|
||||||
|
|
||||||
set (TARGET_SOURCES
|
set (TARGET_SOURCES
|
||||||
src/proxmark3.c
|
${PM3_ROOT}/common/commonutil.c
|
||||||
../common/commonutil.c
|
${PM3_ROOT}/common/util_posix.c
|
||||||
../common/util_posix.c
|
${PM3_ROOT}/common/parity.c
|
||||||
../common/parity.c
|
${PM3_ROOT}/common/bucketsort.c
|
||||||
../common/bucketsort.c
|
${PM3_ROOT}/common/crapto1/crapto1.c
|
||||||
../common/crapto1/crapto1.c
|
${PM3_ROOT}/common/crapto1/crypto1.c
|
||||||
../common/crapto1/crypto1.c
|
${PM3_ROOT}/common/crc.c
|
||||||
../common/crc.c
|
${PM3_ROOT}/common/crc16.c
|
||||||
../common/crc16.c
|
${PM3_ROOT}/common/crc32.c
|
||||||
../common/crc32.c
|
${PM3_ROOT}/common/crc64.c
|
||||||
../common/crc64.c
|
${PM3_ROOT}/common/lfdemod.c
|
||||||
../common/lfdemod.c
|
${PM3_ROOT}/common/legic_prng.c
|
||||||
../common/legic_prng.c
|
${PM3_ROOT}/common/iso15693tools.c
|
||||||
../common/iso15693tools.c
|
${PM3_ROOT}/common/cardhelper.c
|
||||||
../common/cardhelper.c
|
${PM3_ROOT}/common/generator.c
|
||||||
../common/generator.c
|
${PM3_ROOT}/client/src/crypto/asn1dump.c
|
||||||
src/crypto/asn1dump.c
|
${PM3_ROOT}/client/src/crypto/asn1utils.c
|
||||||
src/crypto/asn1utils.c
|
${PM3_ROOT}/client/src/crypto/libpcrypto.c
|
||||||
src/crypto/libpcrypto.c
|
${PM3_ROOT}/client/src/emv/test/cda_test.c
|
||||||
src/emv/test/cda_test.c
|
${PM3_ROOT}/client/src/emv/test/crypto_test.c
|
||||||
src/emv/test/crypto_test.c
|
${PM3_ROOT}/client/src/emv/test/cryptotest.c
|
||||||
src/emv/test/cryptotest.c
|
${PM3_ROOT}/client/src/emv/test/dda_test.c
|
||||||
src/emv/test/dda_test.c
|
${PM3_ROOT}/client/src/emv/test/sda_test.c
|
||||||
src/emv/test/sda_test.c
|
${PM3_ROOT}/client/src/emv/apduinfo.c
|
||||||
src/emv/apduinfo.c
|
${PM3_ROOT}/client/src/emv/cmdemv.c
|
||||||
src/emv/cmdemv.c
|
${PM3_ROOT}/client/src/emv/crypto.c
|
||||||
src/emv/crypto.c
|
${PM3_ROOT}/client/src/emv/crypto_polarssl.c
|
||||||
src/emv/crypto_polarssl.c
|
${PM3_ROOT}/client/src/emv/dol.c
|
||||||
src/emv/dol.c
|
${PM3_ROOT}/client/src/emv/dump.c
|
||||||
src/emv/dump.c
|
${PM3_ROOT}/client/src/emv/emv_pk.c
|
||||||
src/emv/emv_pk.c
|
${PM3_ROOT}/client/src/emv/emv_pki.c
|
||||||
src/emv/emv_pki.c
|
${PM3_ROOT}/client/src/emv/emv_pki_priv.c
|
||||||
src/emv/emv_pki_priv.c
|
${PM3_ROOT}/client/src/emv/emv_roca.c
|
||||||
src/emv/emv_roca.c
|
${PM3_ROOT}/client/src/emv/emv_tags.c
|
||||||
src/emv/emv_tags.c
|
${PM3_ROOT}/client/src/emv/emvcore.c
|
||||||
src/emv/emvcore.c
|
${PM3_ROOT}/client/src/emv/emvjson.c
|
||||||
src/emv/emvjson.c
|
${PM3_ROOT}/client/src/emv/tlv.c
|
||||||
src/emv/tlv.c
|
${PM3_ROOT}/client/src/fido/additional_ca.c
|
||||||
src/fido/additional_ca.c
|
${PM3_ROOT}/client/src/fido/cbortools.c
|
||||||
src/fido/cbortools.c
|
${PM3_ROOT}/client/src/fido/cose.c
|
||||||
src/fido/cose.c
|
${PM3_ROOT}/client/src/fido/fidocore.c
|
||||||
src/fido/fidocore.c
|
${PM3_ROOT}/client/src/loclass/cipher.c
|
||||||
src/loclass/cipher.c
|
${PM3_ROOT}/client/src/loclass/cipherutils.c
|
||||||
src/loclass/cipherutils.c
|
${PM3_ROOT}/client/src/loclass/elite_crack.c
|
||||||
src/loclass/elite_crack.c
|
${PM3_ROOT}/client/src/loclass/hash1_brute.c
|
||||||
src/loclass/hash1_brute.c
|
${PM3_ROOT}/client/src/loclass/ikeys.c
|
||||||
src/loclass/ikeys.c
|
${PM3_ROOT}/client/src/mifare/mad.c
|
||||||
src/mifare/mad.c
|
${PM3_ROOT}/client/src/mifare/mfkey.c
|
||||||
src/mifare/mfkey.c
|
${PM3_ROOT}/client/src/mifare/mifare4.c
|
||||||
src/mifare/mifare4.c
|
${PM3_ROOT}/client/src/mifare/mifaredefault.c
|
||||||
src/mifare/mifaredefault.c
|
${PM3_ROOT}/client/src/mifare/mifarehost.c
|
||||||
src/mifare/mifarehost.c
|
${PM3_ROOT}/client/src/mifare/ndef.c
|
||||||
src/mifare/ndef.c
|
${PM3_ROOT}/client/src/mifare/desfire_crypto.c
|
||||||
src/mifare/desfire_crypto.c
|
${PM3_ROOT}/client/src/uart/uart_posix.c
|
||||||
src/uart/uart_posix.c
|
${PM3_ROOT}/client/src/uart/uart_win32.c
|
||||||
src/uart/uart_win32.c
|
${PM3_ROOT}/client/src/ui/overlays.ui
|
||||||
src/ui/overlays.ui
|
${PM3_ROOT}/client/src/aidsearch.c
|
||||||
src/aidsearch.c
|
${PM3_ROOT}/client/src/cmdanalyse.c
|
||||||
src/cmdanalyse.c
|
${PM3_ROOT}/client/src/cmdcrc.c
|
||||||
src/cmdcrc.c
|
${PM3_ROOT}/client/src/cmddata.c
|
||||||
src/cmddata.c
|
${PM3_ROOT}/client/src/cmdflashmem.c
|
||||||
src/cmdflashmem.c
|
${PM3_ROOT}/client/src/cmdflashmemspiffs.c
|
||||||
src/cmdflashmemspiffs.c
|
${PM3_ROOT}/client/src/cmdhf.c
|
||||||
src/cmdhf.c
|
${PM3_ROOT}/client/src/cmdhf14a.c
|
||||||
src/cmdhf14a.c
|
${PM3_ROOT}/client/src/cmdhf14b.c
|
||||||
src/cmdhf14b.c
|
${PM3_ROOT}/client/src/cmdhf15.c
|
||||||
src/cmdhf15.c
|
${PM3_ROOT}/client/src/cmdhfcryptorf.c
|
||||||
src/cmdhfcryptorf.c
|
${PM3_ROOT}/client/src/cmdhfepa.c
|
||||||
src/cmdhfepa.c
|
${PM3_ROOT}/client/src/cmdhffelica.c
|
||||||
src/cmdhffelica.c
|
${PM3_ROOT}/client/src/cmdhffido.c
|
||||||
src/cmdhffido.c
|
${PM3_ROOT}/client/src/cmdhficlass.c
|
||||||
src/cmdhficlass.c
|
${PM3_ROOT}/client/src/cmdhflegic.c
|
||||||
src/cmdhflegic.c
|
${PM3_ROOT}/client/src/cmdhflist.c
|
||||||
src/cmdhflist.c
|
${PM3_ROOT}/client/src/cmdhflto.c
|
||||||
src/cmdhflto.c
|
${PM3_ROOT}/client/src/cmdhfmf.c
|
||||||
src/cmdhfmf.c
|
${PM3_ROOT}/client/src/cmdhfmfdes.c
|
||||||
src/cmdhfmfdes.c
|
${PM3_ROOT}/client/src/cmdhfmfhard.c
|
||||||
src/cmdhfmfhard.c
|
${PM3_ROOT}/client/src/cmdhfmfp.c
|
||||||
src/cmdhfmfp.c
|
${PM3_ROOT}/client/src/cmdhfmfu.c
|
||||||
src/cmdhfmfu.c
|
${PM3_ROOT}/client/src/cmdhfthinfilm.c
|
||||||
src/cmdhfthinfilm.c
|
${PM3_ROOT}/client/src/cmdhftopaz.c
|
||||||
src/cmdhftopaz.c
|
${PM3_ROOT}/client/src/cmdhw.c
|
||||||
src/cmdhw.c
|
${PM3_ROOT}/client/src/cmdlf.c
|
||||||
src/cmdlf.c
|
${PM3_ROOT}/client/src/cmdlfawid.c
|
||||||
src/cmdlfawid.c
|
${PM3_ROOT}/client/src/cmdlfcotag.c
|
||||||
src/cmdlfcotag.c
|
${PM3_ROOT}/client/src/cmdlfem4x.c
|
||||||
src/cmdlfem4x.c
|
${PM3_ROOT}/client/src/cmdlfem4x50.c
|
||||||
src/cmdlffdx.c
|
${PM3_ROOT}/client/src/cmdlffdx.c
|
||||||
src/cmdlfgallagher.c
|
${PM3_ROOT}/client/src/cmdlfgallagher.c
|
||||||
src/cmdlfguard.c
|
${PM3_ROOT}/client/src/cmdlfguard.c
|
||||||
src/cmdlfhid.c
|
${PM3_ROOT}/client/src/cmdlfhid.c
|
||||||
src/cmdlfhitag.c
|
${PM3_ROOT}/client/src/cmdlfhitag.c
|
||||||
src/cmdlfindala.c
|
${PM3_ROOT}/client/src/cmdlfindala.c
|
||||||
src/cmdlfio.c
|
${PM3_ROOT}/client/src/cmdlfio.c
|
||||||
src/cmdlfjablotron.c
|
${PM3_ROOT}/client/src/cmdlfjablotron.c
|
||||||
src/cmdlfkeri.c
|
${PM3_ROOT}/client/src/cmdlfkeri.c
|
||||||
src/cmdlfmotorola.c
|
${PM3_ROOT}/client/src/cmdlfmotorola.c
|
||||||
src/cmdlfnedap.c
|
${PM3_ROOT}/client/src/cmdlfnedap.c
|
||||||
src/cmdlfnexwatch.c
|
${PM3_ROOT}/client/src/cmdlfnexwatch.c
|
||||||
src/cmdlfnoralsy.c
|
${PM3_ROOT}/client/src/cmdlfnoralsy.c
|
||||||
src/cmdlfpac.c
|
${PM3_ROOT}/client/src/cmdlfpac.c
|
||||||
src/cmdlfparadox.c
|
${PM3_ROOT}/client/src/cmdlfparadox.c
|
||||||
src/cmdlfpcf7931.c
|
${PM3_ROOT}/client/src/cmdlfpcf7931.c
|
||||||
src/cmdlfpresco.c
|
${PM3_ROOT}/client/src/cmdlfpresco.c
|
||||||
src/cmdlfpyramid.c
|
${PM3_ROOT}/client/src/cmdlfpyramid.c
|
||||||
src/cmdlfsecurakey.c
|
${PM3_ROOT}/client/src/cmdlfsecurakey.c
|
||||||
src/cmdlft55xx.c
|
${PM3_ROOT}/client/src/cmdlft55xx.c
|
||||||
src/cmdlfti.c
|
${PM3_ROOT}/client/src/cmdlfti.c
|
||||||
src/cmdlfverichip.c
|
${PM3_ROOT}/client/src/cmdlfverichip.c
|
||||||
src/cmdlfviking.c
|
${PM3_ROOT}/client/src/cmdlfviking.c
|
||||||
src/cmdlfvisa2000.c
|
${PM3_ROOT}/client/src/cmdlfvisa2000.c
|
||||||
src/cmdmain.c
|
${PM3_ROOT}/client/src/cmdmain.c
|
||||||
src/cmdparser.c
|
${PM3_ROOT}/client/src/cmdparser.c
|
||||||
src/cmdscript.c
|
${PM3_ROOT}/client/src/cmdscript.c
|
||||||
src/cmdsmartcard.c
|
${PM3_ROOT}/client/src/cmdsmartcard.c
|
||||||
src/cmdtrace.c
|
${PM3_ROOT}/client/src/cmdtrace.c
|
||||||
src/cmdusart.c
|
${PM3_ROOT}/client/src/cmdusart.c
|
||||||
src/cmdwiegand.c
|
${PM3_ROOT}/client/src/cmdwiegand.c
|
||||||
src/comms.c
|
${PM3_ROOT}/client/src/comms.c
|
||||||
src/fileutils.c
|
${PM3_ROOT}/client/src/fileutils.c
|
||||||
src/flash.c
|
${PM3_ROOT}/client/src/flash.c
|
||||||
src/graph.c
|
${PM3_ROOT}/client/src/graph.c
|
||||||
src/preferences.c
|
${PM3_ROOT}/client/src/jansson_path.c
|
||||||
src/pm3_binlib.c
|
${PM3_ROOT}/client/src/preferences.c
|
||||||
src/pm3_bitlib.c
|
${PM3_ROOT}/client/src/pm3_binlib.c
|
||||||
src/prng.c
|
${PM3_ROOT}/client/src/pm3_bitlib.c
|
||||||
src/scandir.c
|
${PM3_ROOT}/client/src/prng.c
|
||||||
src/scripting.c
|
${PM3_ROOT}/client/src/scandir.c
|
||||||
src/tea.c
|
${PM3_ROOT}/client/src/scripting.c
|
||||||
src/ui.c
|
${PM3_ROOT}/client/src/tea.c
|
||||||
src/util.c
|
${PM3_ROOT}/client/src/ui.c
|
||||||
src/wiegand_formats.c
|
${PM3_ROOT}/client/src/util.c
|
||||||
src/wiegand_formatutils.c
|
${PM3_ROOT}/client/src/wiegand_formats.c
|
||||||
|
${PM3_ROOT}/client/src/wiegand_formatutils.c
|
||||||
|
${CMAKE_BINARY_DIR}/version.c
|
||||||
)
|
)
|
||||||
|
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT ${CMAKE_BINARY_DIR}/version.c
|
||||||
|
COMMAND sh ${PM3_ROOT}/tools/mkversion.sh > ${CMAKE_BINARY_DIR}/version.c || perl ${PM3_ROOT}/tools/mkversion.pl > ${CMAKE_BINARY_DIR}/version.c || ${CMAKE_COMMAND} -E copy ${PM3_ROOT}/common/default_version.c ${CMAKE_BINARY_DIR}/version.c
|
||||||
|
DEPENDS ${PM3_ROOT}/common/default_version.c
|
||||||
|
)
|
||||||
|
|
||||||
set(ADDITIONAL_SRC "")
|
set(ADDITIONAL_SRC "")
|
||||||
set(ADDITIONAL_LNK "")
|
set(ADDITIONAL_LNK "")
|
||||||
|
set(ADDITIONAL_DIRS "")
|
||||||
|
set(ADDITIONAL_LNKDIRS "")
|
||||||
set(X86_CPUS x86 x86_64 i686)
|
set(X86_CPUS x86 x86_64 i686)
|
||||||
|
|
||||||
message(STATUS "CMAKE_SYSTEM_PROCESSOR := ${CMAKE_SYSTEM_PROCESSOR}")
|
message(STATUS "CMAKE_SYSTEM_PROCESSOR := ${CMAKE_SYSTEM_PROCESSOR}")
|
||||||
|
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
message("Apple device detected.")
|
message("Apple device detected.")
|
||||||
set(ADDITIONAL_SRC src/util_darwin.h src/util_darwin.m ${ADDITIONAL_SRC})
|
set(ADDITIONAL_SRC ${PM3_ROOT}/client/src/util_darwin.h ${PM3_ROOT}/client/src/util_darwin.m ${ADDITIONAL_SRC})
|
||||||
set(ADDITIONAL_LNK "-framework Foundation" "-framework AppKit")
|
set(ADDITIONAL_LNK "-framework Foundation" "-framework AppKit")
|
||||||
endif (APPLE)
|
endif (APPLE)
|
||||||
|
|
||||||
if (Qt5_FOUND)
|
if ((NOT SKIPQT EQUAL 1) AND (Qt5_FOUND))
|
||||||
message("Qt5 library found, building gui :)")
|
|
||||||
set(CMAKE_AUTOMOC ON)
|
set(CMAKE_AUTOMOC ON)
|
||||||
set(CMAKE_AUTORCC ON)
|
set(CMAKE_AUTORCC ON)
|
||||||
set(CMAKE_AUTOUIC ON)
|
set(CMAKE_AUTOUIC ON)
|
||||||
set (TARGET_SOURCES
|
set (TARGET_SOURCES
|
||||||
src/proxgui.cpp
|
${PM3_ROOT}/client/src/proxgui.cpp
|
||||||
src/proxguiqt.cpp
|
${PM3_ROOT}/client/src/proxguiqt.cpp
|
||||||
${TARGET_SOURCES})
|
${TARGET_SOURCES})
|
||||||
|
|
||||||
add_definitions("-DHAVE_GUI")
|
add_definitions("-DHAVE_GUI")
|
||||||
set(ADDITIONAL_LNK Qt5::Core Qt5::Widgets Qt5::Gui ${ADDITIONAL_LNK})
|
set(ADDITIONAL_LNK ${Qt5_LIBRARIES} ${ADDITIONAL_LNK})
|
||||||
else (Qt5_FOUND)
|
else ((NOT SKIPQT EQUAL 1) AND (Qt5_FOUND))
|
||||||
message("Qt5 library not found, not building gui")
|
|
||||||
set(TARGET_SOURCES
|
set(TARGET_SOURCES
|
||||||
src/guidummy.cpp
|
${PM3_ROOT}/client/src/guidummy.cpp
|
||||||
${TARGET_SOURCES})
|
${TARGET_SOURCES})
|
||||||
endif (Qt5_FOUND)
|
endif ((NOT SKIPQT EQUAL 1) AND (Qt5_FOUND))
|
||||||
|
|
||||||
if (BLUEZ_FOUND)
|
if (NOT SKIPBT EQUAL 1)
|
||||||
message("Bluez library found, building native Bluetooth support :)")
|
if (BLUEZ_FOUND)
|
||||||
add_definitions("-DHAVE_BLUEZ")
|
add_definitions("-DHAVE_BLUEZ")
|
||||||
set(ADDITIONAL_LNK bluetooth ${ADDITIONAL_LNK})
|
set(ADDITIONAL_LNK ${BLUEZ_LIBRARIES} ${ADDITIONAL_LNK})
|
||||||
endif (BLUEZ_FOUND)
|
endif (BLUEZ_FOUND)
|
||||||
|
endif(NOT SKIPBT EQUAL 1)
|
||||||
|
|
||||||
add_executable(
|
if (JANSSON_FOUND)
|
||||||
proxmark3
|
set(ADDITIONAL_DIRS ${JANSSON_INCLUDE_DIRS} ${ADDITIONAL_DIRS})
|
||||||
|
set(ADDITIONAL_LNK ${JANSSON_LIBRARIES} ${ADDITIONAL_LNK})
|
||||||
|
endif (JANSSON_FOUND)
|
||||||
|
|
||||||
|
if (NOT SKIPPYTHON EQUAL 1)
|
||||||
|
if (PYTHON3EMBED_FOUND)
|
||||||
|
add_definitions(-DHAVE_PYTHON)
|
||||||
|
set(ADDITIONAL_DIRS ${PYTHON3EMBED_INCLUDE_DIRS} ${ADDITIONAL_DIRS})
|
||||||
|
set(ADDITIONAL_LNK ${PYTHON3EMBED_LIBRARIES} ${ADDITIONAL_LNK})
|
||||||
|
set(ADDITIONAL_LNKDIRS ${PYTHON3EMBED_LIBRARY_DIRS} ${ADDITIONAL_LNKDIRS})
|
||||||
|
elseif (PYTHON3_FOUND)
|
||||||
|
add_definitions(-DHAVE_PYTHON)
|
||||||
|
set(ADDITIONAL_DIRS ${PYTHON3_INCLUDE_DIRS} ${ADDITIONAL_DIRS})
|
||||||
|
set(ADDITIONAL_LNK ${PYTHON3_LIBRARIES} ${ADDITIONAL_LNK})
|
||||||
|
set(ADDITIONAL_LNKDIRS ${PYTHON3_LIBRARY_DIRS} ${ADDITIONAL_LNKDIRS})
|
||||||
|
endif (PYTHON3EMBED_FOUND)
|
||||||
|
endif (NOT SKIPPYTHON EQUAL 1)
|
||||||
|
|
||||||
|
if (NOT SKIPREADLINE EQUAL 1)
|
||||||
|
if (READLINE_FOUND)
|
||||||
|
add_definitions("-DHAVE_READLINE")
|
||||||
|
set(ADDITIONAL_DIRS ${READLINE_INCLUDE_DIRS} ${ADDITIONAL_DIRS})
|
||||||
|
set(ADDITIONAL_LNK ${READLINE_LIBRARIES} ${ADDITIONAL_LNK})
|
||||||
|
endif (READLINE_FOUND)
|
||||||
|
endif(NOT SKIPREADLINE EQUAL 1)
|
||||||
|
|
||||||
|
if (BZIP2_FOUND)
|
||||||
|
set(ADDITIONAL_DIRS ${BZIP2_INCLUDE_DIRS} ${ADDITIONAL_DIRS})
|
||||||
|
set(ADDITIONAL_LNK ${BZIP2_LIBRARIES} ${ADDITIONAL_LNK})
|
||||||
|
endif (BZIP2_FOUND)
|
||||||
|
|
||||||
|
if (WHEREAMI_FOUND)
|
||||||
|
set(ADDITIONAL_DIRS ${WHEREAMI_INCLUDE_DIRS} ${ADDITIONAL_DIRS})
|
||||||
|
set(ADDITIONAL_LNK ${WHEREAMI_LIBRARIES} ${ADDITIONAL_LNK})
|
||||||
|
endif (WHEREAMI_FOUND)
|
||||||
|
|
||||||
|
message("===================================================================")
|
||||||
|
if (SKIPQT EQUAL 1)
|
||||||
|
message("GUI support: skipped")
|
||||||
|
else (SKIPQT EQUAL 1)
|
||||||
|
if (Qt5_FOUND)
|
||||||
|
message("GUI support: QT5 found, enabled")
|
||||||
|
else (Qt5_FOUND)
|
||||||
|
message("GUI support: QT5 not found, disabled")
|
||||||
|
endif (Qt5_FOUND)
|
||||||
|
endif (SKIPQT EQUAL 1)
|
||||||
|
|
||||||
|
if (SKIPBT EQUAL 1)
|
||||||
|
message("native BT support: skipped")
|
||||||
|
else (SKIPBT EQUAL 1)
|
||||||
|
if (BLUEZ_FOUND)
|
||||||
|
message("native BT support: Bluez found, enabled")
|
||||||
|
else (BLUEZ_FOUND)
|
||||||
|
message("native BT support: Bluez not found, disabled")
|
||||||
|
endif (BLUEZ_FOUND)
|
||||||
|
endif(SKIPBT EQUAL 1)
|
||||||
|
|
||||||
|
if (SKIPJANSSONSYSTEM EQUAL 1)
|
||||||
|
message("Jansson library: local library forced")
|
||||||
|
else (SKIPJANSSONSYSTEM EQUAL 1)
|
||||||
|
if (JANSSON_FOUND)
|
||||||
|
message("Jansson library: system library found")
|
||||||
|
else (JANSSON_FOUND)
|
||||||
|
message("Jansson library: system library not found, using local library")
|
||||||
|
endif (JANSSON_FOUND)
|
||||||
|
endif (SKIPJANSSONSYSTEM EQUAL 1)
|
||||||
|
|
||||||
|
if (SKIPPYTHON EQUAL 1)
|
||||||
|
message("Python3 library: skipped")
|
||||||
|
else (SKIPPYTHON EQUAL 1)
|
||||||
|
if (PYTHON3EMBED_FOUND)
|
||||||
|
message("Python3 library: Python3 embed found, enabled")
|
||||||
|
elseif (PYTHON_FOUND)
|
||||||
|
message("Python3 library: Python3 found, enabled")
|
||||||
|
else (PYTHON3EMBED_FOUND)
|
||||||
|
message("Python3 library: Python3 not found, disabled")
|
||||||
|
endif (PYTHON3EMBED_FOUND)
|
||||||
|
endif(SKIPPYTHON EQUAL 1)
|
||||||
|
|
||||||
|
if (SKIPREADLINE EQUAL 1)
|
||||||
|
message("Readline library: skipped")
|
||||||
|
else (SKIPREADLINE EQUAL 1)
|
||||||
|
if (READLINE_FOUND)
|
||||||
|
message("Readline library: enabled")
|
||||||
|
else (READLINE_FOUND)
|
||||||
|
message("Readline library: Readline not found, disabled")
|
||||||
|
endif (READLINE_FOUND)
|
||||||
|
endif(SKIPREADLINE EQUAL 1)
|
||||||
|
|
||||||
|
if (SKIPWHEREAMISYSTEM EQUAL 1)
|
||||||
|
message("Whereami library: local library forced")
|
||||||
|
else (SKIPWHEREAMISYSTEM EQUAL 1)
|
||||||
|
if (WHEREAMI_FOUND)
|
||||||
|
message("Whereami library: system library found")
|
||||||
|
else (WHEREAMI_FOUND)
|
||||||
|
message("Whereami library: system library not found, using local library")
|
||||||
|
endif (WHEREAMI_FOUND)
|
||||||
|
endif (SKIPWHEREAMISYSTEM EQUAL 1)
|
||||||
|
message("===================================================================")
|
||||||
|
|
||||||
|
add_executable(proxmark3
|
||||||
|
${PM3_ROOT}/client/src/proxmark3.c
|
||||||
${TARGET_SOURCES}
|
${TARGET_SOURCES}
|
||||||
${ADDITIONAL_SRC}
|
${ADDITIONAL_SRC}
|
||||||
)
|
)
|
||||||
|
|
||||||
target_compile_options(proxmark3 PUBLIC -Wall -Werror -O3)
|
target_compile_options(proxmark3 PUBLIC -Wall -Werror -O3)
|
||||||
|
if (ANDROID)
|
||||||
|
if (NOT SKIPREADLINE EQUAL 1)
|
||||||
|
add_dependencies(proxmark3 ncurses readline)
|
||||||
|
endif (NOT SKIPREADLINE EQUAL 1)
|
||||||
|
add_dependencies(proxmark3 bzip2)
|
||||||
|
endif (ANDROID)
|
||||||
|
|
||||||
if (MINGW)
|
if (MINGW)
|
||||||
# Mingw uses by default Microsoft printf, we want the GNU printf (e.g. for %z)
|
# Mingw uses by default Microsoft printf, we want the GNU printf (e.g. for %z)
|
||||||
|
@ -236,49 +462,64 @@ if (MINGW)
|
||||||
endif (MINGW)
|
endif (MINGW)
|
||||||
|
|
||||||
target_include_directories(proxmark3 PRIVATE
|
target_include_directories(proxmark3 PRIVATE
|
||||||
../common
|
${PM3_ROOT}/common
|
||||||
../common_fpga
|
${PM3_ROOT}/common_fpga
|
||||||
../include
|
${PM3_ROOT}/include
|
||||||
src
|
${PM3_ROOT}/client/src
|
||||||
|
${PM3_ROOT}/client/include
|
||||||
|
${ADDITIONAL_DIRS}
|
||||||
)
|
)
|
||||||
|
|
||||||
if (APPLE)
|
if (NOT APPLE)
|
||||||
set_target_properties(proxmark3 PROPERTIES LINK_FLAGS "-Wl,-F/Library/Frameworks, -L/usr/local/opt/readline/lib")
|
|
||||||
set_target_properties(proxmark3 PROPERTIES COMPILE_FLAGS "-I/usr/local/opt/readline/include")
|
|
||||||
else (APPLE)
|
|
||||||
# required for Raspberry Pi, but breaks with clang (OSX). Need to be at the end of the linker line.
|
# required for Raspberry Pi, but breaks with clang (OSX). Need to be at the end of the linker line.
|
||||||
set(ADDITIONAL_LNK ${ADDITIONAL_LNK} -Wl,--as-needed -latomic -Wl,--no-as-needed)
|
set(ADDITIONAL_LNK ${ADDITIONAL_LNK} -Wl,--as-needed -latomic -Wl,--no-as-needed)
|
||||||
endif (APPLE)
|
endif (NOT APPLE)
|
||||||
|
|
||||||
|
|
||||||
find_library(pm3rrg_rdv4_cliparser REQUIRED)
|
find_library(pm3rrg_rdv4_cliparser REQUIRED)
|
||||||
find_library(pm3rrg_rdv4_jansson REQUIRED)
|
|
||||||
find_library(pm3rrg_rdv4_tinycbor REQUIRED)
|
find_library(pm3rrg_rdv4_tinycbor REQUIRED)
|
||||||
find_library(pm3rrg_rdv4_lua REQUIRED)
|
find_library(pm3rrg_rdv4_lua REQUIRED)
|
||||||
find_library(pm3rrg_rdv4_mbedtls REQUIRED)
|
find_library(pm3rrg_rdv4_mbedtls REQUIRED)
|
||||||
find_library(pm3rrg_rdv4_reveng REQUIRED)
|
find_library(pm3rrg_rdv4_reveng REQUIRED)
|
||||||
find_library(pm3rrg_rdv4_z REQUIRED)
|
|
||||||
find_library(pm3rrg_rdv4_hardnested REQUIRED)
|
find_library(pm3rrg_rdv4_hardnested REQUIRED)
|
||||||
find_library(pm3rrg_rdv4_whereami 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)
|
||||||
|
|
||||||
target_link_libraries(proxmark3 PRIVATE
|
target_link_libraries(proxmark3 PRIVATE
|
||||||
readline
|
|
||||||
pthread
|
|
||||||
m
|
m
|
||||||
pm3rrg_rdv4_mbedtls
|
pm3rrg_rdv4_mbedtls
|
||||||
pm3rrg_rdv4_cliparser
|
pm3rrg_rdv4_cliparser
|
||||||
pm3rrg_rdv4_jansson
|
|
||||||
pm3rrg_rdv4_lua
|
pm3rrg_rdv4_lua
|
||||||
pm3rrg_rdv4_tinycbor
|
pm3rrg_rdv4_tinycbor
|
||||||
pm3rrg_rdv4_amiibo
|
pm3rrg_rdv4_amiibo
|
||||||
pm3rrg_rdv4_reveng
|
pm3rrg_rdv4_reveng
|
||||||
pm3rrg_rdv4_z
|
|
||||||
pm3rrg_rdv4_hardnested
|
pm3rrg_rdv4_hardnested
|
||||||
pm3rrg_rdv4_whereami
|
|
||||||
${ADDITIONAL_LNK})
|
${ADDITIONAL_LNK})
|
||||||
|
|
||||||
|
if (NOT SKIPPTHREAD EQUAL 1)
|
||||||
|
target_link_libraries(proxmark3 PRIVATE pthread)
|
||||||
|
endif (NOT SKIPPTHREAD EQUAL 1)
|
||||||
|
|
||||||
|
if (NOT SKIPPYTHON EQUAL 1)
|
||||||
|
# OSX have a hard time compiling python3 dependency with older cmake.
|
||||||
|
if (PYTHON3EMBED_FOUND OR PYTHON3_FOUND)
|
||||||
|
if (NOT CMAKE_VERSION VERSION_LESS 3.13)
|
||||||
|
target_link_directories(proxmark3 PRIVATE ${ADDITIONAL_LNKDIRS})
|
||||||
|
elseif (APPLE)
|
||||||
|
message( SEND_ERROR "Your CMAKE version is too old for Apple platform, please update to a version >=3.13" )
|
||||||
|
endif (NOT CMAKE_VERSION VERSION_LESS 3.13)
|
||||||
|
endif (PYTHON3EMBED_FOUND OR PYTHON3_FOUND)
|
||||||
|
endif (NOT SKIPPYTHON EQUAL 1)
|
||||||
|
|
||||||
install(TARGETS proxmark3 DESTINATION "bin")
|
install(TARGETS proxmark3 DESTINATION "bin")
|
||||||
install(DIRECTORY cmdscripts lualibs luascripts resources dictionaries DESTINATION "share/proxmark3")
|
install(DIRECTORY cmdscripts lualibs luascripts pyscripts resources dictionaries DESTINATION "share/proxmark3")
|
||||||
|
|
||||||
add_custom_command(OUTPUT lualibs/pm3_cmd.lua
|
add_custom_command(OUTPUT lualibs/pm3_cmd.lua
|
||||||
COMMAND "awk -f pm3_cmd_h2lua.awk ../include/pm3_cmd.h > lualibs/pm3_cmd.lua"
|
COMMAND "awk -f pm3_cmd_h2lua.awk ../include/pm3_cmd.h > lualibs/pm3_cmd.lua"
|
||||||
|
|
822
client/Makefile
822
client/Makefile
|
@ -4,26 +4,163 @@
|
||||||
# the license.
|
# the license.
|
||||||
#-----------------------------------------------------------------------------
|
#-----------------------------------------------------------------------------
|
||||||
|
|
||||||
# reveng will compile without macros, but these may be useful:
|
|
||||||
# Add -DBMPMACRO to use bitmap size constant macros (edit config.h)
|
|
||||||
# Add -DNOFORCE to disable the -F switch
|
|
||||||
# Add -DPRESETS to compile with preset models (edit config.h)
|
|
||||||
|
|
||||||
# Must be called before any Makefile include
|
# Must be called before any Makefile include
|
||||||
ROOT_DIR:=$(dir $(realpath $(lastword $(MAKEFILE_LIST))))
|
ROOT_DIR:=$(dir $(realpath $(lastword $(MAKEFILE_LIST))))
|
||||||
|
|
||||||
include ../Makefile.defs
|
include ../Makefile.defs
|
||||||
|
|
||||||
INSTALLBIN = proxmark3
|
INSTALLBIN = proxmark3
|
||||||
INSTALLSHARE = cmdscripts lualibs luascripts resources dictionaries
|
INSTALLSHARE = cmdscripts lualibs luascripts pyscripts resources dictionaries
|
||||||
|
|
||||||
VPATH = ../common src
|
VPATH = ../common src
|
||||||
vpath %.dic dictionaries
|
vpath %.dic dictionaries
|
||||||
OBJDIR = obj
|
OBJDIR = obj
|
||||||
|
|
||||||
LDLIBS ?= -L/usr/local/lib
|
ifeq ($(platform),Darwin)
|
||||||
LDLIBS += -lreadline -lpthread -lm
|
# cf brew info qt: qt not symlinked anymore
|
||||||
|
PKG_CONFIG_ENV := PKG_CONFIG_PATH=/usr/local/opt/qt/lib/pkgconfig
|
||||||
|
endif
|
||||||
|
|
||||||
|
###################
|
||||||
|
# local libraries #
|
||||||
|
###################
|
||||||
|
|
||||||
|
## Amiibo
|
||||||
|
AMIIBOLIBPATH = ./deps/amiitool
|
||||||
|
AMIIBOLIBINC = -I$(AMIIBOLIBPATH)
|
||||||
|
AMIIBOLIB = $(AMIIBOLIBPATH)/libamiibo.a
|
||||||
|
|
||||||
|
## Cliparser / Argtable3
|
||||||
|
CLIPARSERLIBPATH = ./deps/cliparser
|
||||||
|
CLIPARSERLIBINC = -I$(CLIPARSERLIBPATH)
|
||||||
|
CLIPARSERLIB = $(CLIPARSERLIBPATH)/libcliparser.a
|
||||||
|
|
||||||
|
## Hardnested
|
||||||
|
HARDNESTEDLIBPATH = ./deps/hardnested
|
||||||
|
HARDNESTEDLIBINC = -I$(HARDNESTEDLIBPATH)
|
||||||
|
HARDNESTEDLIB = $(HARDNESTEDLIBPATH)/libhardnested.a
|
||||||
|
|
||||||
|
## Jansson
|
||||||
|
JANSSONLIBPATH = ./deps/jansson
|
||||||
|
JANSSONLIBINC = -I$(JANSSONLIBPATH)
|
||||||
|
JANSSONLIB = $(JANSSONLIBPATH)/libjansson.a
|
||||||
|
|
||||||
|
## Lua
|
||||||
|
LUALIBPATH = ./deps/liblua
|
||||||
|
LUALIBINC = -I$(LUALIBPATH)
|
||||||
|
LUALIB = $(LUALIBPATH)/liblua.a
|
||||||
|
LUAPLATFORM = generic
|
||||||
|
ifneq (,$(findstring MINGW,$(platform)))
|
||||||
|
LUAPLATFORM = mingw
|
||||||
|
else
|
||||||
|
ifeq ($(platform),Darwin)
|
||||||
|
LUAPLATFORM = macosx
|
||||||
|
else
|
||||||
|
LUALIB += -ldl
|
||||||
|
LUAPLATFORM = linux
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
## Reveng
|
||||||
|
REVENGLIBPATH = ./deps/reveng
|
||||||
|
REVENGLIBINC = -I$(REVENGLIBPATH)
|
||||||
|
REVENGLIB = $(REVENGLIBPATH)/libreveng.a
|
||||||
|
|
||||||
|
## Tinycbor
|
||||||
|
TINYCBORLIBPATH = ./deps/tinycbor
|
||||||
|
TINYCBORLIBINC = -I$(TINYCBORLIBPATH)
|
||||||
|
TINYCBORLIB = $(TINYCBORLIBPATH)/tinycbor.a
|
||||||
|
|
||||||
|
## Whereami
|
||||||
|
WHEREAMILIBPATH = ./deps/whereami
|
||||||
|
WHEREAMILIBINC = -I$(WHEREAMILIBPATH)
|
||||||
|
WHEREAMILIB = $(WHEREAMILIBPATH)/libwhereami.a
|
||||||
|
|
||||||
|
##########################
|
||||||
|
# common local libraries #
|
||||||
|
##########################
|
||||||
|
|
||||||
|
## mbed TLS
|
||||||
|
MBEDTLSLIBPATH = ../common/mbedtls
|
||||||
|
MBEDTLSLIBINC = -I$(MBEDTLSLIBPATH)
|
||||||
|
MBEDTLSLIB = $(OBJDIR)/libmbedtls.a
|
||||||
|
|
||||||
|
########################################################
|
||||||
|
# optional system libraries to replace local libraries #
|
||||||
|
########################################################
|
||||||
|
|
||||||
|
## Amiibo
|
||||||
|
# not distributed as system library
|
||||||
|
LDLIBS += $(AMIIBOLIB)
|
||||||
|
INCLUDES += $(AMIIBOLIBINC)
|
||||||
|
|
||||||
|
## Cliparser / Argtable3
|
||||||
|
# not distributed as system library
|
||||||
|
LDLIBS += $(CLIPARSERLIB)
|
||||||
|
INCLUDES += $(CLIPARSERLIBINC)
|
||||||
|
|
||||||
|
## Hardnested
|
||||||
|
# not distributed as system library
|
||||||
|
LDLIBS += $(HARDNESTEDLIB)
|
||||||
|
INCLUDES += $(HARDNESTEDLIBINC)
|
||||||
|
|
||||||
|
## Jansson
|
||||||
|
ifneq ($(SKIPJANSSONSYSTEM),1)
|
||||||
|
JANSSONINCLUDES = $(shell $(PKG_CONFIG_ENV) pkg-config --cflags jansson 2>/dev/null)
|
||||||
|
JANSSONLDLIBS = $(shell $(PKG_CONFIG_ENV) pkg-config --libs jansson 2>/dev/null)
|
||||||
|
ifneq ($(JANSSONLDLIBS),)
|
||||||
|
JANSSONLIB = $(JANSSONLDLIBS)
|
||||||
|
JANSSONLIBINC = $(JANSSONINCLUDES)
|
||||||
|
JANSSON_FOUND = 1
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
LDLIBS += $(JANSSONLIB)
|
||||||
|
INCLUDES += $(JANSSONLIBINC)
|
||||||
|
|
||||||
|
## Lua
|
||||||
|
ifneq ($(SKIPLUASYSTEM),1)
|
||||||
|
LUAINCLUDES = $(shell $(PKG_CONFIG_ENV) pkg-config --cflags lua5.2 2>/dev/null)
|
||||||
|
LUALDLIBS = $(shell $(PKG_CONFIG_ENV) pkg-config --libs lua5.2 2>/dev/null)
|
||||||
|
ifneq ($(LUALDLIBS),)
|
||||||
|
LUALIB = $(LUALDLIBS)
|
||||||
|
LUALIBINC = $(LUAINCLUDES)
|
||||||
|
LUA_FOUND = 1
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
LDLIBS += $(LUALIB)
|
||||||
|
INCLUDES += $(LUALIBINC)
|
||||||
|
|
||||||
|
## mbed TLS
|
||||||
|
# system library cannot be used because it is compiled by default without CMAC support
|
||||||
|
LDLIBS +=$(MBEDTLSLIB)
|
||||||
|
INCLUDES += $(MBEDTLSLIBINC)
|
||||||
|
|
||||||
|
## Reveng
|
||||||
|
# not distributed as system library
|
||||||
|
LDLIBS += $(REVENGLIB)
|
||||||
|
INCLUDES += $(REVENGLIBINC)
|
||||||
|
|
||||||
|
## Tinycbor
|
||||||
|
# not distributed as system library
|
||||||
|
LDLIBS += $(TINYCBORLIB)
|
||||||
|
INCLUDES += $(TINYCBORLIBINC)
|
||||||
|
|
||||||
|
## Whereami
|
||||||
|
ifneq ($(SKIPWHEREAMISYSTEM),1)
|
||||||
|
ifneq (,$(wildcard /usr/include/whereami.h))
|
||||||
|
WHEREAMILIB = -lwhereami
|
||||||
|
WHEREAMILIBINC =
|
||||||
|
WHEREAMI_FOUND = 1
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
LDLIBS += $(WHEREAMILIB)
|
||||||
|
INCLUDES += $(WHEREAMILIBINC)
|
||||||
|
|
||||||
|
####################
|
||||||
|
# system libraries #
|
||||||
|
####################
|
||||||
|
|
||||||
|
## Atomic
|
||||||
# RPi Zero gcc requires -latomic
|
# RPi Zero gcc requires -latomic
|
||||||
# but MacOSX /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld
|
# but MacOSX /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld
|
||||||
# doesn't recognize option --as-needed
|
# doesn't recognize option --as-needed
|
||||||
|
@ -31,38 +168,111 @@ ifneq ($(platform),Darwin)
|
||||||
LDLIBS += -Wl,--as-needed -latomic -Wl,--no-as-needed
|
LDLIBS += -Wl,--as-needed -latomic -Wl,--no-as-needed
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# local libraries
|
## BZIP2
|
||||||
LUALIBPATH = ./deps/liblua
|
LDLIBS += -lbz2
|
||||||
LUALIB = $(LUALIBPATH)/liblua.a
|
|
||||||
JANSSONLIBPATH = ./deps/jansson
|
|
||||||
JANSSONLIB = $(JANSSONLIBPATH)/libjansson.a
|
|
||||||
CBORLIBPATH = ./deps/tinycbor
|
|
||||||
CBORLIB = $(CBORLIBPATH)/tinycbor.a
|
|
||||||
REVENGLIBPATH = ./deps/reveng
|
|
||||||
REVENGLIB = $(REVENGLIBPATH)/libreveng.a
|
|
||||||
AMIIBOLIBPATH = ./deps/amiitool
|
|
||||||
AMIIBOLIB = $(AMIIBOLIBPATH)/libamiibo.a
|
|
||||||
HARDNESTEDLIBPATH = ./deps/hardnested
|
|
||||||
HARDNESTEDLIB = $(HARDNESTEDLIBPATH)/libhardnested.a
|
|
||||||
CLIPARSERLIBPATH = ./deps/cliparser
|
|
||||||
CLIPARSERLIB = $(CLIPARSERLIBPATH)/libcliparser.a
|
|
||||||
WAILIBPATH = ./deps/whereami
|
|
||||||
WAILIB = $(WAILIBPATH)/libwhereami.a
|
|
||||||
|
|
||||||
# common libraries
|
## Bluez (optional)
|
||||||
MBEDTLSLIBPATH = ../common/mbedtls
|
ifneq ($(SKIPBT),1)
|
||||||
MBEDTLSLIB = $(OBJDIR)/libmbedtls.a
|
BTINCLUDES = $(shell $(PKG_CONFIG_ENV) pkg-config --cflags bluez 2>/dev/null)
|
||||||
ZLIBPATH = ../common/zlib
|
BTLDLIBS = $(shell $(PKG_CONFIG_ENV) pkg-config --libs bluez 2>/dev/null)
|
||||||
ZLIB = $(OBJDIR)/libz.a
|
ifneq ($(BTLDLIBS),)
|
||||||
|
BTLIB = $(BTLDLIBS)
|
||||||
|
BTLIBINC = $(BTINCLUDES)
|
||||||
|
BT_FOUND = 1
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
LDLIBS += $(BTLIB)
|
||||||
|
INCLUDES += $(BTLIBINC)
|
||||||
|
|
||||||
LIBS = -I$(LUALIBPATH) -I$(MBEDTLSLIBPATH) -I$(JANSSONLIBPATH) -I$(CBORLIBPATH) -I$(ZLIBPATH) -I$(REVENGLIBPATH) -I$(AMIIBOLIBPATH) -I$(HARDNESTEDLIBPATH) -I$(CLIPARSERLIBPATH) -I$(WAILIBPATH)
|
## Math
|
||||||
INCLUDES_CLIENT += -I./src -I../include -I../common -I../common_fpga $(LIBS)
|
LDLIBS += -lm
|
||||||
|
|
||||||
|
## Pthread
|
||||||
|
# Some have no pthread, e.g. termux
|
||||||
|
ifneq ($(SKIPPTHREAD),1)
|
||||||
|
LDLIBS += -lpthread
|
||||||
|
endif
|
||||||
|
|
||||||
|
## Python3 (optional)
|
||||||
|
ifneq ($(SKIPPYTHON),1)
|
||||||
|
PYTHONINCLUDES = $(shell $(PKG_CONFIG_ENV) pkg-config --cflags python3 2>/dev/null)
|
||||||
|
PYTHONLDLIBS = $(shell $(PKG_CONFIG_ENV) pkg-config --libs python3 2>/dev/null)
|
||||||
|
ifneq ($(PYTHONLDLIBS),)
|
||||||
|
PYTHONLIB = $(PYTHONLDLIBS)
|
||||||
|
PYTHONLIBINC = $(PYTHONINCLUDES)
|
||||||
|
PYTHON_FOUND = 1
|
||||||
|
else
|
||||||
|
# since python3.8, applications willing to embed python must use -embed:
|
||||||
|
PYTHONINCLUDES = $(shell $(PKG_CONFIG_ENV) pkg-config --cflags python3-embed 2>/dev/null)
|
||||||
|
PYTHONLDLIBS = $(shell $(PKG_CONFIG_ENV) pkg-config --libs python3-embed 2>/dev/null)
|
||||||
|
ifneq ($(PYTHONLDLIBS),)
|
||||||
|
PYTHONLIB = $(PYTHONLDLIBS)
|
||||||
|
PYTHONLIBINC = $(PYTHONINCLUDES)
|
||||||
|
PYTHON_FOUND = 1
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
LDLIBS += $(PYTHONLIB)
|
||||||
|
INCLUDES += $(PYTHONLIBINC)
|
||||||
|
|
||||||
|
## QT5 (or QT4 fallback) (optional)
|
||||||
|
ifneq ($(SKIPQT),1)
|
||||||
|
# Check for correctly configured Qt5
|
||||||
|
QTINCLUDES = $(shell $(PKG_CONFIG_ENV) pkg-config --cflags Qt5Core Qt5Widgets 2>/dev/null)
|
||||||
|
QTLDLIBS = $(shell $(PKG_CONFIG_ENV) pkg-config --libs Qt5Core Qt5Widgets 2>/dev/null)
|
||||||
|
MOC = $(shell $(PKG_CONFIG_ENV) pkg-config --variable=host_bins Qt5Core)/moc
|
||||||
|
UIC = $(shell $(PKG_CONFIG_ENV) pkg-config --variable=host_bins Qt5Core)/uic
|
||||||
|
ifneq ($(QTLDLIBS),)
|
||||||
|
QT5_FOUND = 1
|
||||||
|
else
|
||||||
|
# if Qt5 not found check for correctly configured Qt4
|
||||||
|
QTINCLUDES = $(shell $(PKG_CONFIG_ENV) pkg-config --cflags QtCore QtGui 2>/dev/null)
|
||||||
|
QTLDLIBS = $(shell $(PKG_CONFIG_ENV) pkg-config --libs QtCore QtGui 2>/dev/null)
|
||||||
|
MOC = $(shell $(PKG_CONFIG_ENV) pkg-config --variable=moc_location QtCore)
|
||||||
|
UIC = $(shell $(PKG_CONFIG_ENV) pkg-config --variable=uic_location QtCore)
|
||||||
|
endif
|
||||||
|
ifeq ($(QTLDLIBS),)
|
||||||
|
# if both pkg-config commands failed, search in common places
|
||||||
|
ifneq ($(QTDIR),)
|
||||||
|
ifneq ($(wildcard $(QTDIR)/include/QtWidgets),)
|
||||||
|
# QT5
|
||||||
|
QTINCLUDES = -I$(QTDIR)/include -I$(QTDIR)/include/QtCore -I$(QTDIR)/include/QtGui -I$(QTDIR)/include/QtWidgets
|
||||||
|
QTLDLIBS = -L$(QTDIR)/lib -lQt5Core -lQt5Gui -lQt5Widgets
|
||||||
|
QT5_FOUND = 1
|
||||||
|
else
|
||||||
|
# QT4
|
||||||
|
QTINCLUDES = -I$(QTDIR)/include -I$(QTDIR)/include/QtCore -I$(QTDIR)/include/QtGui
|
||||||
|
QTLDLIBS = -L$(QTDIR)/lib -lQtCore4 -lQtGui4
|
||||||
|
endif
|
||||||
|
MOC = $(QTDIR)/bin/moc
|
||||||
|
UIC = $(QTDIR)/bin/uic
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
ifneq ($(QTLDLIBS),)
|
||||||
|
QT_FOUND = 1
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
LDLIBS += $(QTLDLIBS)
|
||||||
|
CXXINCLUDES += $(QTINCLUDES)
|
||||||
|
|
||||||
|
## Readline
|
||||||
|
ifneq ($(SKIPREADLINE),1)
|
||||||
|
ifeq ($(platform),Darwin)
|
||||||
|
LDLIBS += -L/usr/local/opt/readline/lib
|
||||||
|
INCLUDES += -I/usr/local/opt/readline/include
|
||||||
|
endif
|
||||||
|
LDLIBS += -lreadline
|
||||||
|
READLINE_FOUND = 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
#######################################################################################################
|
||||||
CFLAGS ?= $(DEFCFLAGS)
|
CFLAGS ?= $(DEFCFLAGS)
|
||||||
|
|
||||||
# We cannot just use CFLAGS+=... because it has impact on sub-makes if CFLAGS is defined in env:
|
# We cannot just use CFLAGS+=... because it has impact on sub-makes if CFLAGS is defined in env:
|
||||||
PM3CFLAGS = $(CFLAGS) $(INCLUDES_CLIENT)
|
PM3CFLAGS = $(CFLAGS)
|
||||||
|
PM3CFLAGS += -I./src -I../include -I../common -I../common_fpga $(INCLUDES)
|
||||||
# WIP Testing
|
# WIP Testing
|
||||||
#PM3CFLAGS = $(CFLAGS) -std=c11 -pedantic $(INCLUDES_CLIENT)
|
#PM3CFLAGS += -std=c11 -pedantic
|
||||||
|
|
||||||
PREFIX ?= /usr/local
|
PREFIX ?= /usr/local
|
||||||
ifneq (,$(findstring MINGW,$(platform)))
|
ifneq (,$(findstring MINGW,$(platform)))
|
||||||
# Mingw uses by default Microsoft printf, we want the GNU printf (e.g. for %z)
|
# Mingw uses by default Microsoft printf, we want the GNU printf (e.g. for %z)
|
||||||
|
@ -72,253 +282,304 @@ ifneq (,$(findstring MINGW,$(platform)))
|
||||||
PM3CFLAGS += -D_ISOC99_SOURCE
|
PM3CFLAGS += -D_ISOC99_SOURCE
|
||||||
PM3CFLAGS += -mno-ms-bitfields -fexec-charset=cp850
|
PM3CFLAGS += -mno-ms-bitfields -fexec-charset=cp850
|
||||||
endif
|
endif
|
||||||
CXXFLAGS ?= -Wall -Werror -O3
|
|
||||||
PM3CXXFLAGS = $(CXXFLAGS) -I../include
|
|
||||||
|
|
||||||
LUAPLATFORM = generic
|
ifeq ($(READLINE_FOUND),1)
|
||||||
ifneq (,$(findstring MINGW,$(platform)))
|
PM3CFLAGS += -DHAVE_READLINE
|
||||||
LUAPLATFORM = mingw
|
|
||||||
else
|
|
||||||
ifeq ($(platform),Darwin)
|
|
||||||
LUAPLATFORM = macosx
|
|
||||||
OBJCSRCS = util_darwin.m
|
|
||||||
LDFLAGS += -framework Foundation -framework AppKit
|
|
||||||
LDLIBS := -L/usr/local/opt/readline/lib $(LDLIBS)
|
|
||||||
LIBS := -I/usr/local/opt/readline/include $(LIBS)
|
|
||||||
# cf brew info qt: qt not symlinked anymore
|
|
||||||
PKG_CONFIG_ENV := PKG_CONFIG_PATH=/usr/local/opt/qt/lib/pkgconfig
|
|
||||||
else
|
|
||||||
LUALIB += -ldl
|
|
||||||
LUAPLATFORM = linux
|
|
||||||
endif
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq ($(SKIPBT),1)
|
ifeq ($(BT_FOUND),1)
|
||||||
BTLDLIBS = $(shell $(PKG_CONFIG_ENV) pkg-config --libs bluez 2>/dev/null)
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifneq ($(BTLDLIBS),)
|
|
||||||
PM3CFLAGS += -DHAVE_BLUEZ
|
PM3CFLAGS += -DHAVE_BLUEZ
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq ($(SKIPQT),1)
|
ifeq ($(PYTHON_FOUND),1)
|
||||||
# Check for correctly configured Qt5
|
PM3CFLAGS += -DHAVE_PYTHON
|
||||||
QTINCLUDES = $(shell $(PKG_CONFIG_ENV) pkg-config --cflags Qt5Core Qt5Widgets 2>/dev/null)
|
endif
|
||||||
QTLDLIBS = $(shell $(PKG_CONFIG_ENV) pkg-config --libs Qt5Core Qt5Widgets 2>/dev/null)
|
|
||||||
MOC = $(shell $(PKG_CONFIG_ENV) pkg-config --variable=host_bins Qt5Core)/moc
|
|
||||||
UIC = $(shell $(PKG_CONFIG_ENV) pkg-config --variable=host_bins Qt5Core)/uic
|
CXXFLAGS ?= -Wall -Werror -O3
|
||||||
ifeq ($(QTINCLUDES), )
|
PM3CXXFLAGS = $(CXXFLAGS)
|
||||||
# if Qt5 not found check for correctly configured Qt4
|
PM3CXXFLAGS += -I../include
|
||||||
QTINCLUDES = $(shell $(PKG_CONFIG_ENV) pkg-config --cflags QtCore QtGui 2>/dev/null)
|
|
||||||
QTLDLIBS = $(shell $(PKG_CONFIG_ENV) pkg-config --libs QtCore QtGui 2>/dev/null)
|
ifeq ($(QT_FOUND),1)
|
||||||
MOC = $(shell $(PKG_CONFIG_ENV) pkg-config --variable=moc_location QtCore)
|
PM3CFLAGS += -DHAVE_GUI
|
||||||
UIC = $(shell $(PKG_CONFIG_ENV) pkg-config --variable=uic_location QtCore)
|
PM3CXXFLAGS += -DQT_NO_DEBUG
|
||||||
else
|
ifeq ($(QT5_FOUND),1)
|
||||||
# On OSX Qt5 is claiming for a C++11 compiler (gnu++14 works too, but if nothing it fails)
|
# On OSX Qt5 is claiming for a C++11 compiler (gnu++14 works too, but if nothing it fails)
|
||||||
PM3CXXFLAGS += -fPIC -std=c++11
|
PM3CXXFLAGS += -fPIC -std=c++11
|
||||||
endif
|
endif
|
||||||
ifeq ($(QTINCLUDES), )
|
|
||||||
# if both pkg-config commands failed, search in common places
|
|
||||||
ifneq ($(QTDIR), )
|
|
||||||
QTINCLUDES = -I$(QTDIR)/include -I$(QTDIR)/include/QtCore -I$(QTDIR)/include/QtGui
|
|
||||||
QTLDLIBS = -L$(QTDIR)/lib -lQtCore4 -lQtGui4
|
|
||||||
ifneq ($(wildcard $(QTDIR)/include/QtWidgets),)
|
|
||||||
QTINCLUDES += -I$(QTDIR)/include/QtWidgets
|
|
||||||
QTLDLIBS = -L$(QTDIR)/lib -lQt5Widgets -lQt5Gui -lQt5Core
|
|
||||||
PM3CXXFLAGS += -fPIC -std=c++11
|
|
||||||
endif
|
|
||||||
MOC = $(QTDIR)/bin/moc
|
|
||||||
UIC = $(QTDIR)/bin/uic
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq ($(QTLDLIBS),)
|
PM3LDFLAGS = $(LDFLAGS)
|
||||||
QTGUISRCS = proxgui.cpp proxguiqt.cpp proxguiqt.moc.cpp
|
ifeq ($(platform),Darwin)
|
||||||
QTGUIOBJS = $(OBJDIR)/proxgui.o $(OBJDIR)/proxguiqt.o $(OBJDIR)/proxguiqt.moc.o
|
PM3LDFLAGS += -framework Foundation -framework AppKit
|
||||||
PM3CFLAGS += -DHAVE_GUI
|
|
||||||
PM3CXXFLAGS += -DQT_NO_DEBUG
|
|
||||||
else
|
|
||||||
QTGUISRCS = guidummy.cpp
|
|
||||||
QTGUIOBJS = $(OBJDIR)/guidummy.o
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
###################
|
||||||
|
# printing status #
|
||||||
|
###################
|
||||||
|
|
||||||
$(info ===================================================================)
|
$(info ===================================================================)
|
||||||
$(info Client platform: $(platform))
|
$(info Client platform: $(platform))
|
||||||
|
|
||||||
ifeq ($(SKIPQT),1)
|
ifeq ($(SKIPQT),1)
|
||||||
$(info GUI support: skipped)
|
$(info GUI support: skipped)
|
||||||
else ifneq ($(QTLDLIBS),)
|
|
||||||
$(info GUI support: QT found, enabled)
|
|
||||||
else
|
else
|
||||||
$(info GUI support: QT not found, disabled)
|
ifeq ($(QT_FOUND),1)
|
||||||
|
ifeq ($(QT5_FOUND),1)
|
||||||
|
$(info GUI support: QT5 found, enabled)
|
||||||
|
else
|
||||||
|
$(info GUI support: QT4 found, enabled)
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
$(info GUI support: QT not found, disabled)
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(SKIPBT),1)
|
ifeq ($(SKIPBT),1)
|
||||||
$(info native BT support: skipped)
|
$(info native BT support: skipped)
|
||||||
else ifneq ($(BTLDLIBS),)
|
|
||||||
$(info native BT support: Bluez found, enabled)
|
|
||||||
else
|
else
|
||||||
$(info native BT support: Bluez not found, disabled)
|
ifeq ($(BT_FOUND),1)
|
||||||
|
$(info native BT support: Bluez found, enabled)
|
||||||
|
else
|
||||||
|
$(info native BT support: Bluez not found, disabled)
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(SKIPJANSSONSYSTEM),1)
|
||||||
|
$(info Jansson library: local library forced)
|
||||||
|
else ifeq ($(JANSSON_FOUND),1)
|
||||||
|
$(info Jansson library: system library found)
|
||||||
|
else
|
||||||
|
$(info Jansson library: system library not found, using local library)
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(SKIPLUASYSTEM),1)
|
||||||
|
$(info Lua library: local library forced)
|
||||||
|
else
|
||||||
|
ifeq ($(LUA_FOUND),1)
|
||||||
|
$(info Lua library: system library found)
|
||||||
|
else
|
||||||
|
$(info Lua library: system library not found, using local library)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(SKIPPYTHON),1)
|
||||||
|
$(info Python3 library: skipped)
|
||||||
|
else
|
||||||
|
ifeq ($(PYTHON_FOUND),1)
|
||||||
|
$(info Python3 library: Python3 v$(shell pkg-config --modversion python3) found, enabled)
|
||||||
|
else
|
||||||
|
$(info Python3 library: Python3 not found, disabled)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(SKIPREADLINE),1)
|
||||||
|
$(info Readline library: skipped)
|
||||||
|
else
|
||||||
|
ifeq ($(READLINE_FOUND),1)
|
||||||
|
$(info Readline library: enabled)
|
||||||
|
else
|
||||||
|
$(info Readline library: Readline not found, disabled)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(SKIPWHEREAMISYSTEM),1)
|
||||||
|
$(info Whereami library: local library forced)
|
||||||
|
else
|
||||||
|
ifeq ($(WHEREAMI_FOUND),1)
|
||||||
|
$(info Whereami library: system library found)
|
||||||
|
else
|
||||||
|
$(info Whereami library: system library not found, using local library)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
$(info compiler version: $(shell $(CC) --version|head -n 1))
|
$(info compiler version: $(shell $(CC) --version|head -n 1))
|
||||||
$(info ===================================================================)
|
$(info ===================================================================)
|
||||||
|
|
||||||
|
################
|
||||||
|
# dependencies #
|
||||||
|
################
|
||||||
|
|
||||||
# Flags to generate temporary dependency files
|
# Flags to generate temporary dependency files
|
||||||
DEPFLAGS = -MT $@ -MMD -MP -MF $(OBJDIR)/$*.Td
|
DEPFLAGS = -MT $@ -MMD -MP -MF $(OBJDIR)/$*.Td
|
||||||
# make temporary to final dependency files after successful compilation
|
# make temporary to final dependency files after successful compilation
|
||||||
POSTCOMPILE = $(MV) -f $(OBJDIR)/$*.Td $(OBJDIR)/$*.d && $(TOUCH) $@
|
POSTCOMPILE = $(MV) -f $(OBJDIR)/$*.Td $(OBJDIR)/$*.d && $(TOUCH) $@
|
||||||
|
|
||||||
CORESRCS = uart/uart_posix.c \
|
################
|
||||||
uart/uart_win32.c \
|
# enumerations #
|
||||||
ui.c \
|
################
|
||||||
commonutil.c \
|
|
||||||
util.c \
|
|
||||||
util_posix.c \
|
|
||||||
scandir.c \
|
|
||||||
crc16.c \
|
|
||||||
crc32.c \
|
|
||||||
comms.c
|
|
||||||
|
|
||||||
CMDSRCS = crapto1/crapto1.c \
|
SRCS = aidsearch.c \
|
||||||
crapto1/crypto1.c \
|
cmdanalyse.c \
|
||||||
mifare/mifaredefault.c \
|
cmdcrc.c \
|
||||||
mifare/mfkey.c \
|
cmddata.c \
|
||||||
tea.c \
|
cmdflashmem.c \
|
||||||
fido/additional_ca.c \
|
cmdflashmemspiffs.c \
|
||||||
fido/cose.c \
|
cmdhf.c \
|
||||||
fido/cbortools.c \
|
cmdhf14a.c \
|
||||||
fido/fidocore.c \
|
cmdhf14b.c \
|
||||||
crypto/asn1dump.c \
|
cmdhf15.c \
|
||||||
crypto/libpcrypto.c\
|
cmdhfcryptorf.c \
|
||||||
crypto/asn1utils.c\
|
cmdhfepa.c \
|
||||||
loclass/cipher.c \
|
cmdhffelica.c \
|
||||||
loclass/cipherutils.c \
|
cmdhffido.c \
|
||||||
loclass/ikeys.c \
|
cmdhficlass.c \
|
||||||
loclass/elite_crack.c \
|
cmdhflegic.c \
|
||||||
fileutils.c \
|
cmdhflist.c \
|
||||||
mifare/mifarehost.c \
|
cmdhflto.c \
|
||||||
parity.c \
|
cmdhfmf.c \
|
||||||
crc.c \
|
cmdhfmfdes.c \
|
||||||
crc64.c \
|
cmdhfmfhard.c \
|
||||||
legic_prng.c \
|
cmdhfmfu.c \
|
||||||
iso15693tools.c \
|
cmdhfmfp.c \
|
||||||
prng.c \
|
cmdhfthinfilm.c \
|
||||||
generator.c \
|
cmdhftopaz.c \
|
||||||
graph.c \
|
cmdhw.c \
|
||||||
cmddata.c \
|
cmdlf.c \
|
||||||
lfdemod.c \
|
cmdlfawid.c \
|
||||||
emv/crypto_polarssl.c\
|
cmdlfcotag.c \
|
||||||
emv/crypto.c\
|
cmdlfem4x.c \
|
||||||
emv/emv_pk.c\
|
cmdlfem4x50.c \
|
||||||
emv/emv_pki.c\
|
cmdlffdx.c \
|
||||||
emv/emv_pki_priv.c\
|
cmdlfguard.c \
|
||||||
emv/test/cryptotest.c\
|
cmdlfgallagher.c \
|
||||||
emv/apduinfo.c \
|
cmdlfhid.c \
|
||||||
emv/dump.c \
|
cmdlfhitag.c \
|
||||||
emv/tlv.c \
|
cmdlfindala.c \
|
||||||
emv/emv_tags.c \
|
cmdlfio.c \
|
||||||
emv/dol.c \
|
cmdlfjablotron.c \
|
||||||
emv/emvjson.c\
|
cmdlfkeri.c \
|
||||||
emv/emvcore.c \
|
cmdlfmotorola.c \
|
||||||
emv/test/crypto_test.c\
|
cmdlfnedap.c \
|
||||||
emv/test/sda_test.c\
|
cmdlfnexwatch.c \
|
||||||
emv/test/dda_test.c\
|
cmdlfnoralsy.c \
|
||||||
emv/test/cda_test.c\
|
cmdlfpac.c \
|
||||||
emv/cmdemv.c \
|
cmdlfparadox.c \
|
||||||
emv/emv_roca.c \
|
cmdlfpcf7931.c \
|
||||||
mifare/mifare4.c \
|
cmdlfpresco.c \
|
||||||
mifare/mad.c \
|
cmdlfpyramid.c \
|
||||||
mifare/ndef.c \
|
cmdlfsecurakey.c \
|
||||||
mifare/desfire_crypto.c \
|
cmdlft55xx.c \
|
||||||
cmdanalyse.c \
|
cmdlfti.c \
|
||||||
cmdhf.c \
|
cmdlfviking.c \
|
||||||
cmdhflist.c \
|
cmdlfvisa2000.c \
|
||||||
aidsearch.c \
|
cmdmain.c \
|
||||||
cmdhf14a.c \
|
cmdparser.c \
|
||||||
cmdhf14b.c \
|
cmdscript.c \
|
||||||
cmdhf15.c \
|
cmdsmartcard.c \
|
||||||
cmdhfepa.c \
|
cmdtrace.c \
|
||||||
cmdhflegic.c \
|
cmdusart.c \
|
||||||
cmdhficlass.c \
|
cmdwiegand.c \
|
||||||
cmdhfmf.c \
|
comms.c \
|
||||||
cmdhfmfu.c \
|
crypto/asn1dump.c \
|
||||||
cmdhfmfp.c \
|
crypto/asn1utils.c\
|
||||||
cmdhfmfhard.c \
|
crypto/libpcrypto.c\
|
||||||
cmdhfmfdes.c \
|
emv/apduinfo.c \
|
||||||
cmdhftopaz.c \
|
emv/cmdemv.c \
|
||||||
cmdhffido.c \
|
emv/crypto.c\
|
||||||
cmdhffelica.c \
|
emv/crypto_polarssl.c\
|
||||||
cmdhfthinfilm.c \
|
emv/dol.c \
|
||||||
cmdhfcryptorf.c \
|
emv/dump.c \
|
||||||
cmdhflto.c \
|
emv/emv_pk.c\
|
||||||
cmdhw.c \
|
emv/emv_pki.c\
|
||||||
cmdlf.c \
|
emv/emv_pki_priv.c\
|
||||||
cmdlfawid.c \
|
emv/emv_roca.c \
|
||||||
cmdlfcotag.c \
|
emv/emv_tags.c \
|
||||||
cmdlfem4x.c \
|
emv/emvcore.c \
|
||||||
cmdlffdx.c \
|
emv/emvjson.c\
|
||||||
cmdlfguard.c \
|
emv/tlv.c \
|
||||||
cmdlfgallagher.c \
|
emv/test/crypto_test.c\
|
||||||
cmdlfhid.c \
|
emv/test/cryptotest.c\
|
||||||
cmdlfhitag.c \
|
emv/test/cda_test.c\
|
||||||
cmdlfio.c \
|
emv/test/dda_test.c\
|
||||||
cmdlfindala.c \
|
emv/test/sda_test.c\
|
||||||
cmdlfjablotron.c \
|
fido/additional_ca.c \
|
||||||
cmdlfkeri.c \
|
fido/cose.c \
|
||||||
cmdlfnexwatch.c \
|
fido/cbortools.c \
|
||||||
cmdlfnedap.c \
|
fido/fidocore.c \
|
||||||
cmdlfnoralsy.c \
|
fileutils.c \
|
||||||
cmdlfpac.c \
|
flash.c \
|
||||||
cmdlfparadox.c \
|
generator.c \
|
||||||
cmdlfpcf7931.c \
|
graph.c \
|
||||||
cmdlfpresco.c \
|
jansson_path.c \
|
||||||
cmdlfpyramid.c \
|
loclass/cipher.c \
|
||||||
cmdlfsecurakey.c \
|
loclass/cipherutils.c \
|
||||||
cmdlft55xx.c \
|
loclass/elite_crack.c \
|
||||||
cmdlfti.c \
|
loclass/ikeys.c \
|
||||||
cmdlfviking.c \
|
mifare/desfire_crypto.c \
|
||||||
cmdlfvisa2000.c \
|
mifare/mad.c \
|
||||||
cmdlfmotorola.c \
|
mifare/mfkey.c \
|
||||||
cmdtrace.c \
|
mifare/mifare4.c \
|
||||||
cmdflashmem.c \
|
mifare/mifaredefault.c \
|
||||||
cmdflashmemspiffs.c \
|
mifare/mifarehost.c \
|
||||||
cmdsmartcard.c \
|
mifare/ndef.c \
|
||||||
cmdusart.c \
|
pm3_binlib.c \
|
||||||
cmdwiegand.c \
|
pm3_bitlib.c \
|
||||||
cmdparser.c \
|
preferences.c \
|
||||||
cmdmain.c \
|
prng.c \
|
||||||
pm3_binlib.c \
|
proxmark3.c \
|
||||||
scripting.c \
|
scandir.c \
|
||||||
cmdscript.c \
|
uart/uart_posix.c \
|
||||||
pm3_bitlib.c \
|
uart/uart_win32.c \
|
||||||
cmdcrc.c \
|
scripting.c \
|
||||||
bucketsort.c \
|
tea.c \
|
||||||
flash.c \
|
ui.c \
|
||||||
wiegand_formats.c \
|
util.c \
|
||||||
wiegand_formatutils.c \
|
version.c \
|
||||||
cardhelper.c \
|
wiegand_formats.c \
|
||||||
preferences.c
|
wiegand_formatutils.c
|
||||||
|
|
||||||
|
# common
|
||||||
|
SRCS += bucketsort.c \
|
||||||
|
cardhelper.c \
|
||||||
|
crapto1/crapto1.c \
|
||||||
|
crapto1/crypto1.c \
|
||||||
|
crc.c \
|
||||||
|
crc16.c \
|
||||||
|
crc32.c \
|
||||||
|
crc64.c \
|
||||||
|
commonutil.c \
|
||||||
|
iso15693tools.c \
|
||||||
|
legic_prng.c \
|
||||||
|
lfdemod.c \
|
||||||
|
parity.c \
|
||||||
|
util_posix.c
|
||||||
|
|
||||||
|
# gui
|
||||||
|
ifeq ($(QT_FOUND),1)
|
||||||
|
CXXSRCS = proxgui.cpp proxguiqt.cpp proxguiqt.moc.cpp
|
||||||
|
else
|
||||||
|
CXXSRCS = guidummy.cpp
|
||||||
|
endif
|
||||||
|
|
||||||
COREOBJS = $(CORESRCS:%.c=$(OBJDIR)/%.o)
|
# OS X
|
||||||
CMDOBJS = $(CMDSRCS:%.c=$(OBJDIR)/%.o)
|
ifeq ($(platform),Darwin)
|
||||||
OBJCOBJS = $(OBJCSRCS:%.m=$(OBJDIR)/%.o)
|
OBJCSRCS = util_darwin.m
|
||||||
|
endif
|
||||||
|
|
||||||
|
OBJS = $(SRCS:%.c=$(OBJDIR)/%.o)
|
||||||
|
OBJS += $(CXXSRCS:%.cpp=$(OBJDIR)/%.o)
|
||||||
|
OBJS += $(OBJCSRCS:%.m=$(OBJDIR)/%.o)
|
||||||
|
|
||||||
BINS = proxmark3
|
BINS = proxmark3
|
||||||
CLEAN = $(BINS) src/*.moc.cpp src/ui/ui_overlays.h lualibs/pm3_cmd.lua lualibs/mfc_default_keys.lua
|
|
||||||
|
CLEAN = $(BINS) src/version.c src/*.moc.cpp src/ui/ui_overlays.h lualibs/pm3_cmd.lua lualibs/mfc_default_keys.lua
|
||||||
# transition: cleaning also old path stuff
|
# transition: cleaning also old path stuff
|
||||||
CLEAN += flasher *.moc.cpp ui/ui_overlays.h
|
CLEAN += flasher *.moc.cpp ui/ui_overlays.h
|
||||||
|
|
||||||
|
###########
|
||||||
|
# targets #
|
||||||
|
###########
|
||||||
|
|
||||||
# need to assign dependancies to build these first...
|
# need to assign dependancies to build these first...
|
||||||
all: $(BINS)
|
all: $(BINS)
|
||||||
|
|
||||||
all-static: LDLIBS:=-static $(LDLIBS)
|
all-static: LDLIBS:=-static $(LDLIBS)
|
||||||
all-static: $(BINS)
|
all-static: $(BINS)
|
||||||
|
|
||||||
proxmark3: LDLIBS+=$(LUALIB) $(JANSSONLIB) $(MBEDTLSLIB) $(CBORLIB) $(ZLIB) $(REVENGLIB) $(AMIIBOLIB) $(HARDNESTEDLIB) $(CLIPARSERLIB) $(WAILIB) $(BTLDLIBS) $(QTLDLIBS)
|
proxmark3: $(OBJS) amiibo cliparser jansson hardnested lua mbedtls reveng tinycbor whereami lualibs/pm3_cmd.lua lualibs/mfc_default_keys.lua
|
||||||
proxmark3: $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(QTGUIOBJS) liblua jansson tinycbor reveng mbedtls zlib amiibo hardnested cliparser whereami lualibs/pm3_cmd.lua lualibs/mfc_default_keys.lua
|
|
||||||
$(info [=] LD $@)
|
$(info [=] LD $@)
|
||||||
$(Q)$(LD) $(LDFLAGS) $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(QTGUIOBJS) $(LDLIBS) -o $@
|
$(Q)$(LD) $(PM3LDFLAGS) $(OBJS) $(LDLIBS) -o $@
|
||||||
|
|
||||||
src/proxgui.cpp: src/ui/ui_overlays.h
|
src/proxgui.cpp: src/ui/ui_overlays.h
|
||||||
|
|
||||||
|
@ -341,16 +602,15 @@ lualibs/mfc_default_keys.lua : mfc_default_keys.dic
|
||||||
clean:
|
clean:
|
||||||
$(Q)$(RM) $(CLEAN)
|
$(Q)$(RM) $(CLEAN)
|
||||||
$(Q)$(RMDIR) $(OBJDIR)
|
$(Q)$(RMDIR) $(OBJDIR)
|
||||||
$(Q)$(MAKE) --no-print-directory -C $(LUALIBPATH) clean
|
|
||||||
$(Q)$(MAKE) --no-print-directory -C $(JANSSONLIBPATH) clean
|
|
||||||
$(Q)$(MAKE) --no-print-directory -C $(CBORLIBPATH) clean
|
|
||||||
$(Q)$(MAKE) --no-print-directory -C $(REVENGLIBPATH) clean
|
|
||||||
$(Q)$(MAKE) --no-print-directory -C $(AMIIBOLIBPATH) clean
|
$(Q)$(MAKE) --no-print-directory -C $(AMIIBOLIBPATH) clean
|
||||||
$(Q)$(MAKE) --no-print-directory -C $(HARDNESTEDLIBPATH) clean
|
|
||||||
$(Q)$(MAKE) --no-print-directory -C $(CLIPARSERLIBPATH) clean
|
$(Q)$(MAKE) --no-print-directory -C $(CLIPARSERLIBPATH) clean
|
||||||
$(Q)$(MAKE) --no-print-directory -C $(WAILIBPATH) clean
|
$(Q)$(MAKE) --no-print-directory -C $(HARDNESTEDLIBPATH) clean
|
||||||
|
$(Q)$(MAKE) --no-print-directory -C $(JANSSONLIBPATH) clean
|
||||||
|
$(Q)$(MAKE) --no-print-directory -C $(LUALIBPATH) clean
|
||||||
|
$(Q)$(MAKE) --no-print-directory -C $(REVENGLIBPATH) clean
|
||||||
|
$(Q)$(MAKE) --no-print-directory -C $(TINYCBORLIBPATH) clean
|
||||||
|
$(Q)$(MAKE) --no-print-directory -C $(WHEREAMILIBPATH) clean
|
||||||
@# Just in case someone compiled within these dirs:
|
@# Just in case someone compiled within these dirs:
|
||||||
$(Q)$(MAKE) --no-print-directory -C $(ZLIBPATH) clean
|
|
||||||
$(Q)$(MAKE) --no-print-directory -C $(MBEDTLSLIBPATH) clean
|
$(Q)$(MAKE) --no-print-directory -C $(MBEDTLSLIBPATH) clean
|
||||||
|
|
||||||
install: all
|
install: all
|
||||||
|
@ -379,26 +639,9 @@ tarbin: $(BINS)
|
||||||
$(info [=] TAR ../proxmark3-$(platform)-bin.tar)
|
$(info [=] TAR ../proxmark3-$(platform)-bin.tar)
|
||||||
$(Q)$(TAR) $(TARFLAGS) ../proxmark3-$(platform)-bin.tar $(BINS:%=client/%) $(WINBINS:%=client/%)
|
$(Q)$(TAR) $(TARFLAGS) ../proxmark3-$(platform)-bin.tar $(BINS:%=client/%) $(WINBINS:%=client/%)
|
||||||
|
|
||||||
# local libraries:
|
###########################
|
||||||
liblua:
|
# local libraries targets #
|
||||||
$(info [*] MAKE $@ for $(LUAPLATFORM))
|
###########################
|
||||||
$(Q)$(MAKE) --no-print-directory -C $(LUALIBPATH) $(LUAPLATFORM)
|
|
||||||
|
|
||||||
jansson:
|
|
||||||
$(info [*] MAKE $@)
|
|
||||||
$(Q)$(MAKE) --no-print-directory -C $(JANSSONLIBPATH) all
|
|
||||||
|
|
||||||
tinycbor:
|
|
||||||
$(info [*] MAKE $@)
|
|
||||||
$(Q)$(MAKE) --no-print-directory -C $(CBORLIBPATH) all
|
|
||||||
|
|
||||||
reveng:
|
|
||||||
$(info [*] MAKE $@)
|
|
||||||
$(Q)$(MAKE) --no-print-directory -C $(REVENGLIBPATH) all
|
|
||||||
|
|
||||||
hardnested:
|
|
||||||
$(info [*] MAKE $@)
|
|
||||||
$(Q)$(MAKE) --no-print-directory -C $(HARDNESTEDLIBPATH) all
|
|
||||||
|
|
||||||
amiibo:
|
amiibo:
|
||||||
$(info [*] MAKE $@)
|
$(info [*] MAKE $@)
|
||||||
|
@ -408,20 +651,50 @@ cliparser:
|
||||||
$(info [*] MAKE $@)
|
$(info [*] MAKE $@)
|
||||||
$(Q)$(MAKE) --no-print-directory -C $(CLIPARSERLIBPATH) all
|
$(Q)$(MAKE) --no-print-directory -C $(CLIPARSERLIBPATH) all
|
||||||
|
|
||||||
whereami:
|
hardnested:
|
||||||
$(info [*] MAKE $@)
|
$(info [*] MAKE $@)
|
||||||
$(Q)$(MAKE) --no-print-directory -C $(WAILIBPATH) all
|
$(Q)$(MAKE) --no-print-directory -C $(HARDNESTEDLIBPATH) all
|
||||||
|
|
||||||
|
jansson:
|
||||||
|
ifneq ($(JANSSON_FOUND),1)
|
||||||
|
$(info [*] MAKE $@)
|
||||||
|
$(Q)$(MAKE) --no-print-directory -C $(JANSSONLIBPATH) all
|
||||||
|
endif
|
||||||
|
|
||||||
|
lua:
|
||||||
|
ifneq ($(LUA_FOUND),1)
|
||||||
|
$(info [*] MAKE $@ for $(LUAPLATFORM))
|
||||||
|
$(Q)$(MAKE) --no-print-directory -C $(LUALIBPATH) $(LUAPLATFORM)
|
||||||
|
endif
|
||||||
|
|
||||||
# common libraries:
|
|
||||||
mbedtls:
|
mbedtls:
|
||||||
$(info [*] MAKE $@)
|
$(info [*] MAKE $@)
|
||||||
$(Q)$(MAKE) --no-print-directory -C $(MBEDTLSLIBPATH) OBJDIR=$(ROOT_DIR)$(OBJDIR) BINDIR=$(ROOT_DIR)$(OBJDIR) all
|
$(Q)$(MAKE) --no-print-directory -C $(MBEDTLSLIBPATH) OBJDIR=$(ROOT_DIR)$(OBJDIR) BINDIR=$(ROOT_DIR)$(OBJDIR) all
|
||||||
|
|
||||||
zlib:
|
reveng:
|
||||||
$(info [*] MAKE $@)
|
$(info [*] MAKE $@)
|
||||||
$(Q)$(MAKE) --no-print-directory -C $(ZLIBPATH) OBJDIR=$(ROOT_DIR)$(OBJDIR) BINDIR=$(ROOT_DIR)$(OBJDIR) all
|
$(Q)$(MAKE) --no-print-directory -C $(REVENGLIBPATH) all
|
||||||
|
|
||||||
.PHONY: all clean install uninstall tarbin liblua jansson tinycbor reveng hardnested amiibo cliparser whereami mbedtls zlib
|
tinycbor:
|
||||||
|
$(info [*] MAKE $@)
|
||||||
|
$(Q)$(MAKE) --no-print-directory -C $(TINYCBORLIBPATH) all
|
||||||
|
|
||||||
|
whereami:
|
||||||
|
ifneq ($(WHEREAMI_FOUND),1)
|
||||||
|
$(info [*] MAKE $@)
|
||||||
|
$(Q)$(MAKE) --no-print-directory -C $(WHEREAMILIBPATH) all
|
||||||
|
endif
|
||||||
|
|
||||||
|
########
|
||||||
|
# misc #
|
||||||
|
########
|
||||||
|
|
||||||
|
.PHONY: all clean install uninstall tarbin amiibo cliparser hardnested jansson lua mbedtls reveng tinycbor whereami
|
||||||
|
|
||||||
|
# version.c should be remade on every compilation
|
||||||
|
src/version.c: default_version.c
|
||||||
|
$(info [=] GEN $@)
|
||||||
|
$(Q)$(SH) ../tools/mkversion.sh > $@ || $(PERL) ../tools/mkversion.pl > $@ || $(CP) $< $@
|
||||||
|
|
||||||
# easy printing of MAKE VARIABLES
|
# easy printing of MAKE VARIABLES
|
||||||
print-%: ; @echo $* = $($*)
|
print-%: ; @echo $* = $($*)
|
||||||
|
@ -437,7 +710,7 @@ $(OBJDIR)/%.o : %.c $(OBJDIR)/%.d
|
||||||
$(OBJDIR)/%.o : %.cpp $(OBJDIR)/%.d
|
$(OBJDIR)/%.o : %.cpp $(OBJDIR)/%.d
|
||||||
$(info [-] CXX $<)
|
$(info [-] CXX $<)
|
||||||
$(Q)$(MKDIR) $(dir $@)
|
$(Q)$(MKDIR) $(dir $@)
|
||||||
$(Q)$(CXX) $(DEPFLAGS) $(PM3CXXFLAGS) $(QTINCLUDES) -c -o $@ $<
|
$(Q)$(CXX) $(DEPFLAGS) $(PM3CXXFLAGS) $(CXXINCLUDES) -c -o $@ $<
|
||||||
$(Q)$(POSTCOMPILE)
|
$(Q)$(POSTCOMPILE)
|
||||||
|
|
||||||
%.o: %.m
|
%.o: %.m
|
||||||
|
@ -447,10 +720,9 @@ $(OBJDIR)/%.o : %.m $(OBJDIR)/%.d
|
||||||
$(Q)$(CC) $(DEPFLAGS) $(PM3CFLAGS) -c -o $@ $<
|
$(Q)$(CC) $(DEPFLAGS) $(PM3CFLAGS) -c -o $@ $<
|
||||||
$(Q)$(POSTCOMPILE)
|
$(Q)$(POSTCOMPILE)
|
||||||
|
|
||||||
DEPENDENCY_FILES = $(patsubst %.c, $(OBJDIR)/%.d, $(CORESRCS) $(CMDSRCS)) \
|
DEPENDENCY_FILES = $(patsubst %.c, $(OBJDIR)/%.d, $(SRCS)) \
|
||||||
$(patsubst %.cpp, $(OBJDIR)/%.d, $(QTGUISRCS)) \
|
$(patsubst %.cpp, $(OBJDIR)/%.d, $(CXXSRCS)) \
|
||||||
$(patsubst %.m, $(OBJDIR)/%.d, $(OBJCSRCS)) \
|
$(patsubst %.m, $(OBJDIR)/%.d, $(OBJCSRCS))
|
||||||
$(OBJDIR)/proxmark3.d
|
|
||||||
|
|
||||||
$(DEPENDENCY_FILES): ;
|
$(DEPENDENCY_FILES): ;
|
||||||
.PRECIOUS: $(DEPENDENCY_FILES)
|
.PRECIOUS: $(DEPENDENCY_FILES)
|
||||||
|
|
|
@ -145,6 +145,7 @@ add_library(pm3rrg_rdv4 SHARED
|
||||||
${PM3_ROOT}/client/src/cmdlfpcf7931.c
|
${PM3_ROOT}/client/src/cmdlfpcf7931.c
|
||||||
${PM3_ROOT}/client/src/cmdhfmfhard.c
|
${PM3_ROOT}/client/src/cmdhfmfhard.c
|
||||||
${PM3_ROOT}/client/src/cmdusart.c
|
${PM3_ROOT}/client/src/cmdusart.c
|
||||||
|
${PM3_ROOT}/client/src/jansson_path.c
|
||||||
# android resources
|
# android resources
|
||||||
jni_tools.c
|
jni_tools.c
|
||||||
pm3_main.c
|
pm3_main.c
|
||||||
|
@ -164,12 +165,11 @@ find_library(pm3rrg_rdv4_tinycbor REQUIRED)
|
||||||
find_library(pm3rrg_rdv4_lua REQUIRED)
|
find_library(pm3rrg_rdv4_lua REQUIRED)
|
||||||
find_library(pm3rrg_rdv4_mbedtls REQUIRED)
|
find_library(pm3rrg_rdv4_mbedtls REQUIRED)
|
||||||
find_library(pm3rrg_rdv4_reveng REQUIRED)
|
find_library(pm3rrg_rdv4_reveng REQUIRED)
|
||||||
find_library(pm3rrg_rdv4_z REQUIRED)
|
|
||||||
find_library(pm3rrg_rdv4_hardnested REQUIRED)
|
find_library(pm3rrg_rdv4_hardnested REQUIRED)
|
||||||
find_library(pm3rrg_rdv4_whereami REQUIRED)
|
find_library(pm3rrg_rdv4_whereami REQUIRED)
|
||||||
|
|
||||||
target_link_libraries(
|
target_link_libraries(pm3rrg_rdv4
|
||||||
pm3rrg_rdv4
|
bz2
|
||||||
pm3rrg_rdv4_hardnested
|
pm3rrg_rdv4_hardnested
|
||||||
pm3rrg_rdv4_mbedtls
|
pm3rrg_rdv4_mbedtls
|
||||||
pm3rrg_rdv4_cliparser
|
pm3rrg_rdv4_cliparser
|
||||||
|
@ -179,6 +179,5 @@ target_link_libraries(
|
||||||
pm3rrg_rdv4_amiibo
|
pm3rrg_rdv4_amiibo
|
||||||
pm3rrg_rdv4_reveng
|
pm3rrg_rdv4_reveng
|
||||||
pm3rrg_rdv4_whereami
|
pm3rrg_rdv4_whereami
|
||||||
pm3rrg_rdv4_z
|
|
||||||
android
|
android
|
||||||
log)
|
log)
|
||||||
|
|
|
@ -27,74 +27,67 @@
|
||||||
#include "fileutils.h"
|
#include "fileutils.h"
|
||||||
#include "jni_tools.h"
|
#include "jni_tools.h"
|
||||||
|
|
||||||
#define LOCAL_SOCKET_SERVER_NAME "DXL.COM.ASL"
|
//iceman, todo: proxify socker server name. Maybe set in preferences?
|
||||||
|
#define PM3_LOCAL_SOCKET_SERVER "DXL.COM.ASL"
|
||||||
void ShowGraphWindow() {
|
|
||||||
|
|
||||||
|
void ShowGraphWindow(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void HideGraphWindow(void) {
|
void HideGraphWindow(void) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RepaintGraphWindow() {
|
void RepaintGraphWindow(void) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int push_cmdscriptfile(char *path, bool stayafter) {
|
int push_cmdscriptfile(char *path, bool stayafter) {
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *my_executable_path = NULL;
|
static char *g_android_executable_directory = NULL;
|
||||||
static char *my_executable_directory = NULL;
|
static const char *g_android_user_directory = NULL;
|
||||||
|
|
||||||
const char *get_my_executable_path(void) {
|
const char *get_executable_directory(void) {
|
||||||
return my_executable_path;
|
|
||||||
|
if (g_android_executable_directory == NULL) {
|
||||||
|
char buf[FILE_PATH_SIZE] = {0};
|
||||||
|
getcwd(buf, sizeof(buf));
|
||||||
|
strncat(buf, PATHSEP, 1);
|
||||||
|
g_android_executable_directory = strdup(buf);
|
||||||
|
}
|
||||||
|
return g_android_executable_directory;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *get_my_executable_directory(void) {
|
const char *get_user_directory(void) {
|
||||||
return my_executable_directory;
|
return g_android_user_directory;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_my_executable_path(void) {
|
static bool OpenPm3(void) {
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char *my_user_directory = NULL;
|
|
||||||
|
|
||||||
const char *get_my_user_directory(void) {
|
|
||||||
return my_user_directory;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void set_my_user_directory(void) {
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool open() {
|
|
||||||
if (conn.run) {
|
if (conn.run) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// Open with LocalSocket(Not a tcp connection!)
|
// Open with LocalSocket. Not a tcp connection!
|
||||||
bool ret = OpenProxmark("socket:"LOCAL_SOCKET_SERVER_NAME, false, 1000, false, 115200);
|
bool ret = OpenProxmark("socket:"PM3_LOCAL_SOCKET_SERVER, false, 1000, false, 115200);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Transfers to the command buffer and waits for a new command to be executed
|
* Transfers to the command buffer and waits for a new command to be executed
|
||||||
* */
|
* */
|
||||||
jint sendCMD(JNIEnv *env, jobject instance, jstring cmd_) {
|
jint Console(JNIEnv *env, jobject instance, jstring cmd_) {
|
||||||
//may be pm3 not running.
|
|
||||||
if (!conn.run) {
|
if (!conn.run) {
|
||||||
if (open() && TestProxmark() == PM3_SUCCESS) {
|
if (OpenPm3() && TestProxmark() == PM3_SUCCESS) {
|
||||||
LOGD("Open Successfully!");
|
LOGD("Connected to device");
|
||||||
PrintAndLogEx(NORMAL, "Open Successfully!");
|
PrintAndLogEx(SUCCESS, "Connected to device");
|
||||||
} else {
|
} else {
|
||||||
LOGD("Open failed!");
|
LOGD("Failed to connect to device");
|
||||||
PrintAndLogEx(NORMAL, "Open failed!");
|
PrintAndLogEx(ERR, "Failed to connect to device");
|
||||||
CloseProxmark();
|
CloseProxmark();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// display on new line
|
|
||||||
PrintAndLogEx(NORMAL, "\n");
|
PrintAndLogEx(NORMAL, "");
|
||||||
|
|
||||||
char *cmd = (char *)((*env)->GetStringUTFChars(env, cmd_, 0));
|
char *cmd = (char *)((*env)->GetStringUTFChars(env, cmd_, 0));
|
||||||
int ret = CommandReceived(cmd);
|
int ret = CommandReceived(cmd);
|
||||||
if (ret == 99) {
|
if (ret == 99) {
|
||||||
|
@ -102,6 +95,7 @@ jint sendCMD(JNIEnv *env, jobject instance, jstring cmd_) {
|
||||||
// TODO: implement this
|
// TODO: implement this
|
||||||
PrintAndLogEx(NORMAL, "Asked to exit, can't really do that yet...");
|
PrintAndLogEx(NORMAL, "Asked to exit, can't really do that yet...");
|
||||||
}
|
}
|
||||||
|
|
||||||
(*env)->ReleaseStringUTFChars(env, cmd_, cmd);
|
(*env)->ReleaseStringUTFChars(env, cmd_, cmd);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -109,33 +103,34 @@ jint sendCMD(JNIEnv *env, jobject instance, jstring cmd_) {
|
||||||
/*
|
/*
|
||||||
* Is client running!
|
* Is client running!
|
||||||
* */
|
* */
|
||||||
jboolean isExecuting(JNIEnv *env, jobject instance) {
|
jboolean IsClientRunning(JNIEnv *env, jobject instance) {
|
||||||
return (jboolean)((jboolean) conn.run);
|
return (jboolean)((jboolean) conn.run);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* test hw and hw and client.
|
* test hw and hw and client.
|
||||||
* */
|
* */
|
||||||
jboolean testPm3(JNIEnv *env, jobject instance) {
|
jboolean TestPm3(JNIEnv *env, jobject instance) {
|
||||||
bool ret1 = open();
|
if (open() == false) {
|
||||||
if (!ret1) {
|
|
||||||
CloseProxmark();
|
CloseProxmark();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool ret2 = TestProxmark() == PM3_SUCCESS;
|
bool ret = (TestProxmark() == PM3_SUCCESS);
|
||||||
return (jboolean)(ret1 && ret2);
|
return (jboolean)(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* stop pm3 client
|
* stop pm3 client
|
||||||
* */
|
* */
|
||||||
void stopPm3(JNIEnv *env, jobject instance) {
|
void ClosePm3(JNIEnv *env, jobject instance) {
|
||||||
CloseProxmark();
|
CloseProxmark();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* native function map to jvm
|
* native function map to jvm
|
||||||
* */
|
* */
|
||||||
|
|
||||||
|
//iceman: todo, pm3:ify java class root. Return codes, should match PM3_E* codes.
|
||||||
JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) {
|
JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) {
|
||||||
JNIEnv *jniEnv = NULL;
|
JNIEnv *jniEnv = NULL;
|
||||||
if ((*vm)->GetEnv(vm, (void **) &jniEnv, JNI_VERSION_1_4) != JNI_OK) {
|
if ((*vm)->GetEnv(vm, (void **) &jniEnv, JNI_VERSION_1_4) != JNI_OK) {
|
||||||
|
@ -148,23 +143,24 @@ JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) {
|
||||||
}
|
}
|
||||||
jclass clz_test = (*jniEnv)->FindClass(jniEnv, "cn/rrg/devices/Proxmark3RRGRdv4");
|
jclass clz_test = (*jniEnv)->FindClass(jniEnv, "cn/rrg/devices/Proxmark3RRGRdv4");
|
||||||
JNINativeMethod methods[] = {
|
JNINativeMethod methods[] = {
|
||||||
{"startExecute", "(Ljava/lang/String;)I", (void *) sendCMD},
|
{"startExecute", "(Ljava/lang/String;)I", (void *) Console},
|
||||||
{"stopExecute", "()V", (void *) stopPm3},
|
{"stopExecute", "()V", (void *) ClosePm3},
|
||||||
{"isExecuting", "()Z", (void *) isExecuting}
|
{"isExecuting", "()Z", (void *) IsClientRunning}
|
||||||
};
|
};
|
||||||
|
|
||||||
JNINativeMethod methods1[] = {
|
JNINativeMethod methods1[] = {
|
||||||
{"testPm3", "()Z", (void *) testPm3},
|
{"testPm3", "()Z", (void *) TestPm3},
|
||||||
{"closePm3", "()V", stopPm3}
|
{"closePm3", "()V", ClosePm3}
|
||||||
};
|
};
|
||||||
if ((*jniEnv)->RegisterNatives(jniEnv, clazz, methods, sizeof(methods) / sizeof(methods[0])) !=
|
|
||||||
JNI_OK) {
|
if ((*jniEnv)->RegisterNatives(jniEnv, clazz, methods, sizeof(methods) / sizeof(methods[0])) != JNI_OK) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if ((*jniEnv)->RegisterNatives(jniEnv, clz_test, methods1,
|
|
||||||
sizeof(methods1) / sizeof(methods1[0])) !=
|
if ((*jniEnv)->RegisterNatives(jniEnv, clz_test, methods1, sizeof(methods1) / sizeof(methods1[0])) != JNI_OK) {
|
||||||
JNI_OK) {
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*jniEnv)->DeleteLocalRef(jniEnv, clazz);
|
(*jniEnv)->DeleteLocalRef(jniEnv, clazz);
|
||||||
(*jniEnv)->DeleteLocalRef(jniEnv, clz_test);
|
(*jniEnv)->DeleteLocalRef(jniEnv, clz_test);
|
||||||
return JNI_VERSION_1_4;
|
return JNI_VERSION_1_4;
|
||||||
|
|
|
@ -1,10 +1,27 @@
|
||||||
include(cliparser.cmake)
|
if (NOT TARGET pm3rrg_rdv4_amiibo)
|
||||||
include(tinycbor.cmake)
|
include(amiibo.cmake)
|
||||||
include(jansson.cmake)
|
endif()
|
||||||
include(lua.cmake)
|
if (NOT TARGET pm3rrg_rdv4_cliparser)
|
||||||
include(mbedtls.cmake)
|
include(cliparser.cmake)
|
||||||
include(amiibo.cmake)
|
endif()
|
||||||
include(reveng.cmake)
|
if (NOT TARGET pm3rrg_rdv4_hardnested)
|
||||||
include(zlib.cmake)
|
include(hardnested.cmake)
|
||||||
include(hardnested.cmake)
|
endif()
|
||||||
include(whereami.cmake)
|
if (NOT TARGET pm3rrg_rdv4_jansson)
|
||||||
|
include(jansson.cmake)
|
||||||
|
endif()
|
||||||
|
if (NOT TARGET pm3rrg_rdv4_lua)
|
||||||
|
include(lua.cmake)
|
||||||
|
endif()
|
||||||
|
if (NOT TARGET pm3rrg_rdv4_mbedtls)
|
||||||
|
include(mbedtls.cmake)
|
||||||
|
endif()
|
||||||
|
if (NOT TARGET pm3rrg_rdv4_reveng)
|
||||||
|
include(reveng.cmake)
|
||||||
|
endif()
|
||||||
|
if (NOT TARGET pm3rrg_rdv4_tinycbor)
|
||||||
|
include(tinycbor.cmake)
|
||||||
|
endif()
|
||||||
|
if (NOT TARGET pm3rrg_rdv4_whereami)
|
||||||
|
include(whereami.cmake)
|
||||||
|
endif()
|
||||||
|
|
|
@ -11,6 +11,13 @@ add_library(pm3rrg_rdv4_amiibo STATIC
|
||||||
amiitool/keygen.c
|
amiitool/keygen.c
|
||||||
)
|
)
|
||||||
|
|
||||||
|
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)
|
||||||
target_include_directories(pm3rrg_rdv4_amiibo PRIVATE ../../include ../../common)
|
target_include_directories(pm3rrg_rdv4_amiibo PRIVATE ../../include ../../common)
|
||||||
target_include_directories(pm3rrg_rdv4_amiibo INTERFACE amiitool)
|
target_include_directories(pm3rrg_rdv4_amiibo INTERFACE amiitool)
|
||||||
target_compile_options(pm3rrg_rdv4_amiibo PRIVATE -Wall -Werror -O3)
|
target_compile_options(pm3rrg_rdv4_amiibo PRIVATE -Wall -Werror -O3)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
MYSRCPATHS =
|
MYSRCPATHS =
|
||||||
MYINCLUDES = -I. -I.. -I../jansson -I../../../common -I../../../include
|
MYINCLUDES = -I. -I.. -I../jansson -I../../../common -I../../../common/mbedtls -I../../../include
|
||||||
MYCFLAGS =
|
MYCFLAGS =
|
||||||
MYDEFS =
|
MYDEFS =
|
||||||
MYSRCS = \
|
MYSRCS = \
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "amiibo.h"
|
#include "amiibo.h"
|
||||||
#include "mbedtls/md.h"
|
#include "md.h"
|
||||||
#include "mbedtls/aes.h"
|
#include "aes.h"
|
||||||
#include "commonutil.h"
|
#include "commonutil.h"
|
||||||
|
|
||||||
#define HMAC_POS_DATA 0x008
|
#define HMAC_POS_DATA 0x008
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#include "drbg.h"
|
#include "drbg.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "mbedtls/md.h"
|
#include "md.h"
|
||||||
|
|
||||||
void nfc3d_drbg_init(nfc3d_drbg_ctx *ctx, const uint8_t *hmacKey, size_t hmacKeySize, const uint8_t *seed, size_t seedSize) {
|
void nfc3d_drbg_init(nfc3d_drbg_ctx *ctx, const uint8_t *hmacKey, size_t hmacKeySize, const uint8_t *seed, size_t seedSize) {
|
||||||
assert(ctx != NULL);
|
assert(ctx != NULL);
|
||||||
|
|
|
@ -3398,13 +3398,13 @@ void trex_free(TRex *exp) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TRexBool trex_match(TRex *exp, const TRexChar *text) {
|
TRexBool trex_match(TRex *exp, const TRexChar *text) {
|
||||||
const TRexChar *res = NULL;
|
|
||||||
exp->_bol = text;
|
exp->_bol = text;
|
||||||
exp->_eol = text + scstrlen(text);
|
exp->_eol = text + scstrlen(text);
|
||||||
exp->_currsubexp = 0;
|
exp->_currsubexp = 0;
|
||||||
res = trex_matchnode(exp, exp->_nodes, text, NULL);
|
const TRexChar *res = trex_matchnode(exp, exp->_nodes, text, NULL);
|
||||||
if (res == NULL || res != exp->_eol)
|
if (res == NULL || res != exp->_eol) {
|
||||||
return TRex_False;
|
return TRex_False;
|
||||||
|
}
|
||||||
return TRex_True;
|
return TRex_True;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,50 +10,53 @@
|
||||||
|
|
||||||
#include "cliparser.h"
|
#include "cliparser.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#ifndef ARRAYLEN
|
||||||
|
# define ARRAYLEN(x) (sizeof(x)/sizeof((x)[0]))
|
||||||
|
#endif
|
||||||
|
|
||||||
void **argtable = NULL;
|
int CLIParserInit(CLIParserContext **ctx, const char *vprogramName, const char *vprogramHint, const char *vprogramHelp) {
|
||||||
size_t argtableLen = 0;
|
*ctx = malloc(sizeof(CLIParserContext));
|
||||||
const char *programName = NULL;
|
if (!*ctx) {
|
||||||
const char *programHint = NULL;
|
printf("ERROR: Insufficient memory\n");
|
||||||
const char *programHelp = NULL;
|
fflush(stdout);
|
||||||
char buf[500] = {0};
|
return 2;
|
||||||
|
}
|
||||||
int CLIParserInit(const char *vprogramName, const char *vprogramHint, const char *vprogramHelp) {
|
(*ctx)->argtable = NULL;
|
||||||
argtable = NULL;
|
(*ctx)->argtableLen = 0;
|
||||||
argtableLen = 0;
|
(*ctx)->programName = vprogramName;
|
||||||
programName = vprogramName;
|
(*ctx)->programHint = vprogramHint;
|
||||||
programHint = vprogramHint;
|
(*ctx)->programHelp = vprogramHelp;
|
||||||
programHelp = vprogramHelp;
|
memset((*ctx)->buf, 0x00, sizeof((*ctx)->buf));
|
||||||
memset(buf, 0x00, 500);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CLIParserParseArg(int argc, char **argv, void *vargtable[], size_t vargtableLen, bool allowEmptyExec) {
|
int CLIParserParseArg(CLIParserContext *ctx, int argc, char **argv, void *vargtable[], size_t vargtableLen, bool allowEmptyExec) {
|
||||||
int nerrors;
|
int nerrors;
|
||||||
|
|
||||||
argtable = vargtable;
|
ctx->argtable = vargtable;
|
||||||
argtableLen = vargtableLen;
|
ctx->argtableLen = vargtableLen;
|
||||||
|
|
||||||
/* verify the argtable[] entries were allocated sucessfully */
|
/* verify the argtable[] entries were allocated sucessfully */
|
||||||
if (arg_nullcheck(argtable) != 0) {
|
if (arg_nullcheck(ctx->argtable) != 0) {
|
||||||
/* NULL entries were detected, some allocations must have failed */
|
/* NULL entries were detected, some allocations must have failed */
|
||||||
printf("ERROR: Insufficient memory\n");
|
printf("ERROR: Insufficient memory\n");
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
/* Parse the command line as defined by argtable[] */
|
/* Parse the command line as defined by argtable[] */
|
||||||
nerrors = arg_parse(argc, argv, argtable);
|
nerrors = arg_parse(argc, argv, ctx->argtable);
|
||||||
|
|
||||||
/* special case: '--help' takes precedence over error reporting */
|
/* special case: '--help' takes precedence over error reporting */
|
||||||
if ((argc < 2 && !allowEmptyExec) || ((struct arg_lit *)argtable[0])->count > 0) { // help must be the first record
|
if ((argc < 2 && !allowEmptyExec) || ((struct arg_lit *)(ctx->argtable)[0])->count > 0) { // help must be the first record
|
||||||
printf("Usage: %s", programName);
|
printf("Usage: %s", ctx->programName);
|
||||||
arg_print_syntaxv(stdout, argtable, "\n");
|
arg_print_syntaxv(stdout, ctx->argtable, "\n");
|
||||||
if (programHint)
|
if (ctx->programHint)
|
||||||
printf("%s\n\n", programHint);
|
printf("%s\n\n", ctx->programHint);
|
||||||
arg_print_glossary(stdout, argtable, " %-20s %s\n");
|
arg_print_glossary(stdout, ctx->argtable, " %-20s %s\n");
|
||||||
printf("\n");
|
printf("\n");
|
||||||
if (programHelp)
|
if (ctx->programHelp)
|
||||||
printf("%s \n", programHelp);
|
printf("%s \n", ctx->programHelp);
|
||||||
|
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -62,8 +65,8 @@ int CLIParserParseArg(int argc, char **argv, void *vargtable[], size_t vargtable
|
||||||
/* If the parser returned any errors then display them and exit */
|
/* If the parser returned any errors then display them and exit */
|
||||||
if (nerrors > 0) {
|
if (nerrors > 0) {
|
||||||
/* Display the error details contained in the arg_end struct.*/
|
/* Display the error details contained in the arg_end struct.*/
|
||||||
arg_print_errors(stdout, ((struct arg_end *)argtable[vargtableLen - 1]), programName);
|
arg_print_errors(stdout, ((struct arg_end *)(ctx->argtable)[vargtableLen - 1]), ctx->programName);
|
||||||
printf("Try '%s --help' for more information.\n", programName);
|
printf("Try '%s --help' for more information.\n", ctx->programName);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
|
@ -79,23 +82,24 @@ enum ParserState {
|
||||||
|
|
||||||
#define isSpace(c)(c == ' ' || c == '\t')
|
#define isSpace(c)(c == ' ' || c == '\t')
|
||||||
|
|
||||||
int CLIParserParseString(const char *str, void *vargtable[], size_t vargtableLen, bool allowEmptyExec) {
|
int CLIParserParseString(CLIParserContext *ctx, const char *str, void *vargtable[], size_t vargtableLen, bool allowEmptyExec) {
|
||||||
return CLIParserParseStringEx(str, vargtable, vargtableLen, allowEmptyExec, false);
|
return CLIParserParseStringEx(ctx, str, vargtable, vargtableLen, allowEmptyExec, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
int CLIParserParseStringEx(const char *str, void *vargtable[], size_t vargtableLen, bool allowEmptyExec, bool clueData) {
|
int CLIParserParseStringEx(CLIParserContext *ctx, const char *str, void *vargtable[], size_t vargtableLen, bool allowEmptyExec, bool clueData) {
|
||||||
int argc = 0;
|
int argc = 0;
|
||||||
char *argv[200] = {NULL};
|
char *argv[200] = {NULL};
|
||||||
|
|
||||||
int len = strlen(str);
|
int len = strlen(str);
|
||||||
char *bufptr = buf;
|
memset(ctx->buf, 0x00, ARRAYLEN(ctx->buf));
|
||||||
|
char *bufptr = ctx->buf;
|
||||||
char *spaceptr = NULL;
|
char *spaceptr = NULL;
|
||||||
enum ParserState state = PS_FIRST;
|
enum ParserState state = PS_FIRST;
|
||||||
|
|
||||||
argv[argc++] = bufptr;
|
argv[argc++] = bufptr;
|
||||||
// param0 = program name
|
// param0 = program name
|
||||||
memcpy(buf, programName, strlen(programName) + 1); // with 0x00
|
memcpy(ctx->buf, ctx->programName, strlen(ctx->programName) + 1); // with 0x00
|
||||||
bufptr += strlen(programName) + 1;
|
bufptr += strlen(ctx->programName) + 1;
|
||||||
if (len)
|
if (len)
|
||||||
argv[argc++] = bufptr;
|
argv[argc++] = bufptr;
|
||||||
|
|
||||||
|
@ -140,14 +144,7 @@ int CLIParserParseStringEx(const char *str, void *vargtable[], size_t vargtableL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return CLIParserParseArg(argc, argv, vargtable, vargtableLen, allowEmptyExec);
|
return CLIParserParseArg(ctx, argc, argv, vargtable, vargtableLen, allowEmptyExec);
|
||||||
}
|
|
||||||
|
|
||||||
void CLIParserFree(void) {
|
|
||||||
arg_freetable(argtable, argtableLen);
|
|
||||||
argtable = NULL;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// convertors
|
// convertors
|
||||||
|
|
|
@ -11,32 +11,41 @@
|
||||||
#ifndef __CLIPARSER_H
|
#ifndef __CLIPARSER_H
|
||||||
#define __CLIPARSER_H
|
#define __CLIPARSER_H
|
||||||
#include "argtable3.h"
|
#include "argtable3.h"
|
||||||
|
#include <stdlib.h>
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
#define arg_param_begin arg_lit0("hH", "help", "This help")
|
#define arg_param_begin arg_lit0("hH", "help", "This help")
|
||||||
#define arg_param_end arg_end(20)
|
#define arg_param_end arg_end(20)
|
||||||
|
|
||||||
#define arg_getsize(a) (sizeof(a) / sizeof(a[0]))
|
#define arg_getsize(a) (sizeof(a) / sizeof(a[0]))
|
||||||
#define arg_get_lit(n) (((struct arg_lit*)argtable[n])->count)
|
#define arg_get_lit(ctx, n) (((struct arg_lit*)((ctx)->argtable)[n])->count)
|
||||||
#define arg_get_int_count(n)(((struct arg_int*)argtable[n])->count)
|
#define arg_get_int_count(ctx, n)(((struct arg_int*)((ctx)->argtable)[n])->count)
|
||||||
#define arg_get_int(n) (((struct arg_int*)argtable[n])->ival[0])
|
#define arg_get_int(ctx, n) (((struct arg_int*)((ctx)->argtable)[n])->ival[0])
|
||||||
#define arg_get_int_def(n, def)(arg_get_int_count(n) ? (arg_get_int(n)) : (def))
|
#define arg_get_int_def(ctx, n, def)(arg_get_int_count((ctx), n) ? (arg_get_int((ctx), n)) : (def))
|
||||||
#define arg_get_str(n) ((struct arg_str*)argtable[n])
|
#define arg_get_str(ctx, n) ((struct arg_str*)((ctx)->argtable)[n])
|
||||||
#define arg_get_str_len(n) (strlen(((struct arg_str*)argtable[n])->sval[0]))
|
#define arg_get_str_len(ctx, n) (strlen(((struct arg_str*)((ctx)->argtable)[n])->sval[0]))
|
||||||
|
|
||||||
#define arg_strx1(shortopts, longopts, datatype, glossary) (arg_strn((shortopts), (longopts), (datatype), 1, 250, (glossary)))
|
#define arg_strx1(shortopts, longopts, datatype, glossary) (arg_strn((shortopts), (longopts), (datatype), 1, 250, (glossary)))
|
||||||
#define arg_strx0(shortopts, longopts, datatype, glossary) (arg_strn((shortopts), (longopts), (datatype), 0, 250, (glossary)))
|
#define arg_strx0(shortopts, longopts, datatype, glossary) (arg_strn((shortopts), (longopts), (datatype), 0, 250, (glossary)))
|
||||||
|
|
||||||
#define CLIExecWithReturn(cmd, atbl, ifempty) if (CLIParserParseString(cmd, atbl, arg_getsize(atbl), ifempty)){CLIParserFree();return PM3_ESOFT;}
|
#define CLIParserFree(ctx) if ((ctx)) {arg_freetable(ctx->argtable, ctx->argtableLen); free((ctx)); (ctx)=NULL;}
|
||||||
#define CLIGetHexBLessWithReturn(paramnum, data, datalen, delta) if (CLIParamHexToBuf(arg_get_str(paramnum), data, sizeof(data) - (delta), datalen)) {CLIParserFree();return PM3_ESOFT;}
|
#define CLIExecWithReturn(ctx, cmd, atbl, ifempty) if (CLIParserParseString(ctx, cmd, atbl, arg_getsize(atbl), ifempty)) {CLIParserFree((ctx)); return PM3_ESOFT;}
|
||||||
#define CLIGetHexWithReturn(paramnum, data, datalen) if (CLIParamHexToBuf(arg_get_str(paramnum), data, sizeof(data), datalen)) {CLIParserFree();return PM3_ESOFT;}
|
#define CLIGetHexBLessWithReturn(ctx, paramnum, data, datalen, delta) if (CLIParamHexToBuf(arg_get_str(ctx, paramnum), data, sizeof(data) - (delta), datalen)) {CLIParserFree((ctx)); return PM3_ESOFT;}
|
||||||
#define CLIGetStrWithReturn(paramnum, data, datalen) if (CLIParamStrToBuf(arg_get_str(paramnum), data, sizeof(data), datalen)) {CLIParserFree();return PM3_ESOFT;}
|
#define CLIGetHexWithReturn(ctx, paramnum, data, datalen) if (CLIParamHexToBuf(arg_get_str(ctx, paramnum), data, sizeof(data), datalen)) {CLIParserFree((ctx)); return PM3_ESOFT;}
|
||||||
|
#define CLIGetStrWithReturn(ctx, paramnum, data, datalen) if (CLIParamStrToBuf(arg_get_str(ctx, paramnum), data, sizeof(data), datalen)) {CLIParserFree((ctx)); return PM3_ESOFT;}
|
||||||
|
|
||||||
int CLIParserInit(const char *vprogramName, const char *vprogramHint, const char *vprogramHelp);
|
typedef struct {
|
||||||
int CLIParserParseString(const char *str, void *vargtable[], size_t vargtableLen, bool allowEmptyExec);
|
void **argtable;
|
||||||
int CLIParserParseStringEx(const char *str, void *vargtable[], size_t vargtableLen, bool allowEmptyExec, bool clueData);
|
size_t argtableLen;
|
||||||
int CLIParserParseArg(int argc, char **argv, void *vargtable[], size_t vargtableLen, bool allowEmptyExec);
|
const char *programName;
|
||||||
void CLIParserFree(void);
|
const char *programHint;
|
||||||
|
const char *programHelp;
|
||||||
|
char buf[1024 + 60];
|
||||||
|
} CLIParserContext;
|
||||||
|
int CLIParserInit(CLIParserContext **ctx, const char *vprogramName, const char *vprogramHint, const char *vprogramHelp);
|
||||||
|
int CLIParserParseString(CLIParserContext *ctx, const char *str, void *vargtable[], size_t vargtableLen, bool allowEmptyExec);
|
||||||
|
int CLIParserParseStringEx(CLIParserContext *ctx, const char *str, void *vargtable[], size_t vargtableLen, bool allowEmptyExec, bool clueData);
|
||||||
|
int CLIParserParseArg(CLIParserContext *ctx, int argc, char **argv, void *vargtable[], size_t vargtableLen, bool allowEmptyExec);
|
||||||
|
|
||||||
int CLIParamHexToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int *datalen);
|
int CLIParamHexToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int *datalen);
|
||||||
int CLIParamStrToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int *datalen);
|
int CLIParamStrToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int *datalen);
|
||||||
|
|
|
@ -107,6 +107,7 @@ add_library(pm3rrg_rdv4_hardnested STATIC
|
||||||
hardnested/hardnested_bruteforce.c
|
hardnested/hardnested_bruteforce.c
|
||||||
$<TARGET_OBJECTS:pm3rrg_rdv4_hardnested_nosimd>
|
$<TARGET_OBJECTS:pm3rrg_rdv4_hardnested_nosimd>
|
||||||
${SIMD_TARGETS})
|
${SIMD_TARGETS})
|
||||||
|
target_compile_options(pm3rrg_rdv4_hardnested PRIVATE -Wall -Werror -O3)
|
||||||
set_property(TARGET pm3rrg_rdv4_hardnested PROPERTY POSITION_INDEPENDENT_CODE ON)
|
set_property(TARGET pm3rrg_rdv4_hardnested PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||||
target_include_directories(pm3rrg_rdv4_hardnested PRIVATE
|
target_include_directories(pm3rrg_rdv4_hardnested PRIVATE
|
||||||
../../common
|
../../common
|
||||||
|
|
|
@ -557,17 +557,22 @@ void SetSIMDInstr(SIMDExecInstr instr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static SIMDExecInstr GetSIMDInstr(void) {
|
static SIMDExecInstr GetSIMDInstr(void) {
|
||||||
SIMDExecInstr instr = SIMD_NONE;
|
SIMDExecInstr instr;
|
||||||
|
|
||||||
#if defined(COMPILER_HAS_SIMD_AVX512)
|
#if defined(COMPILER_HAS_SIMD_AVX512)
|
||||||
if (__builtin_cpu_supports("avx512f")) instr = SIMD_AVX512;
|
if (__builtin_cpu_supports("avx512f"))
|
||||||
|
instr = SIMD_AVX512;
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
#if defined(COMPILER_HAS_SIMD)
|
#if defined(COMPILER_HAS_SIMD)
|
||||||
if (__builtin_cpu_supports("avx2")) instr = SIMD_AVX2;
|
if (__builtin_cpu_supports("avx2"))
|
||||||
else if (__builtin_cpu_supports("avx")) instr = SIMD_AVX;
|
instr = SIMD_AVX2;
|
||||||
else if (__builtin_cpu_supports("sse2")) instr = SIMD_SSE2;
|
else if (__builtin_cpu_supports("avx"))
|
||||||
else if (__builtin_cpu_supports("mmx")) instr = SIMD_MMX;
|
instr = SIMD_AVX;
|
||||||
|
else if (__builtin_cpu_supports("sse2"))
|
||||||
|
instr = SIMD_SSE2;
|
||||||
|
else if (__builtin_cpu_supports("mmx"))
|
||||||
|
instr = SIMD_MMX;
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
instr = SIMD_NONE;
|
instr = SIMD_NONE;
|
||||||
|
|
|
@ -9,7 +9,6 @@ add_library(pm3rrg_rdv4_jansson STATIC
|
||||||
jansson/strbuffer.c
|
jansson/strbuffer.c
|
||||||
jansson/strconv.c
|
jansson/strconv.c
|
||||||
jansson/utf.c
|
jansson/utf.c
|
||||||
jansson/path.c
|
|
||||||
jansson/value.c
|
jansson/value.c
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,6 @@ MYSRCS = \
|
||||||
strbuffer.c \
|
strbuffer.c \
|
||||||
strconv.c \
|
strconv.c \
|
||||||
utf.c \
|
utf.c \
|
||||||
path.c \
|
|
||||||
value.c
|
value.c
|
||||||
|
|
||||||
LIB_A = libjansson.a
|
LIB_A = libjansson.a
|
||||||
|
|
|
@ -302,14 +302,6 @@ int json_equal(const json_t *json1, const json_t *json2);
|
||||||
json_t *json_copy(json_t *json) JANSSON_ATTRS(warn_unused_result);
|
json_t *json_copy(json_t *json) JANSSON_ATTRS(warn_unused_result);
|
||||||
json_t *json_deep_copy(const json_t *json) JANSSON_ATTRS(warn_unused_result);
|
json_t *json_deep_copy(const json_t *json) JANSSON_ATTRS(warn_unused_result);
|
||||||
|
|
||||||
json_t *json_path_get(const json_t *json, const char *path);
|
|
||||||
int json_path_set_new(json_t *json, const char *path, json_t *value, size_t flags, json_error_t *error);
|
|
||||||
|
|
||||||
static JSON_INLINE
|
|
||||||
int json_path_set(json_t *json, const char *path, json_t *value, size_t flags, json_error_t *error) {
|
|
||||||
return json_path_set_new(json, path, json_incref(value), flags, error);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* decoding */
|
/* decoding */
|
||||||
|
|
||||||
#define JSON_REJECT_DUPLICATES 0x1
|
#define JSON_REJECT_DUPLICATES 0x1
|
||||||
|
|
|
@ -1040,8 +1040,6 @@ json_t *json_loadfd(int input, size_t flags, json_error_t *error) {
|
||||||
|
|
||||||
json_t *json_load_file(const char *path, size_t flags, json_error_t *error) {
|
json_t *json_load_file(const char *path, size_t flags, json_error_t *error) {
|
||||||
json_t *result;
|
json_t *result;
|
||||||
FILE *fp;
|
|
||||||
|
|
||||||
jsonp_error_init(error, path);
|
jsonp_error_init(error, path);
|
||||||
|
|
||||||
if (path == NULL) {
|
if (path == NULL) {
|
||||||
|
@ -1049,15 +1047,13 @@ json_t *json_load_file(const char *path, size_t flags, json_error_t *error) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
fp = fopen(path, "rb");
|
FILE *fp = fopen(path, "rb");
|
||||||
if (!fp) {
|
if (!fp) {
|
||||||
error_set(error, NULL, json_error_cannot_open_file, "unable to open %s: %s",
|
error_set(error, NULL, json_error_cannot_open_file, "unable to open %s: %s", path, strerror(errno));
|
||||||
path, strerror(errno));
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = json_loadf(fp, flags, error);
|
result = json_loadf(fp, flags, error);
|
||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,13 @@ target_compile_definitions(pm3rrg_rdv4_lua PRIVATE LUA_COMPAT_ALL)
|
||||||
if (NOT MINGW)
|
if (NOT MINGW)
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
target_compile_definitions(pm3rrg_rdv4_lua PRIVATE LUA_USE_MACOSX)
|
target_compile_definitions(pm3rrg_rdv4_lua PRIVATE LUA_USE_MACOSX)
|
||||||
|
elseif (ANDROID)
|
||||||
|
# Required:
|
||||||
|
add_definitions(-D"getlocaledecpoint\(\)='.'")
|
||||||
|
# Same as for LUA_USE_LINUX except LUA_USE_POSIX and client-specific LUA_USE_READLINE
|
||||||
|
target_compile_definitions(pm3rrg_rdv4_lua PRIVATE LUA_USE_DLOPEN LUA_USE_STRTODHEX LUA_USE_AFORMAT LUA_USE_LONGLONG)
|
||||||
|
# Same as for LUA_USE_POSIX except client-specific LUA_USE_ISATTY. LUA_USE_MKSTEMP is needed.
|
||||||
|
target_compile_definitions(pm3rrg_rdv4_lua PRIVATE LUA_USE_MKSTEMP LUA_USE_POPEN LUA_USE_ULONGJMP LUA_USE_GMTIME_R)
|
||||||
else (APPLE)
|
else (APPLE)
|
||||||
target_compile_definitions(pm3rrg_rdv4_lua PRIVATE LUA_USE_LINUX)
|
target_compile_definitions(pm3rrg_rdv4_lua PRIVATE LUA_USE_LINUX)
|
||||||
target_link_libraries(pm3rrg_rdv4_lua INTERFACE dl)
|
target_link_libraries(pm3rrg_rdv4_lua INTERFACE dl)
|
||||||
|
|
|
@ -45,5 +45,6 @@ add_library(pm3rrg_rdv4_mbedtls STATIC
|
||||||
)
|
)
|
||||||
|
|
||||||
target_include_directories(pm3rrg_rdv4_mbedtls PRIVATE ../../common)
|
target_include_directories(pm3rrg_rdv4_mbedtls PRIVATE ../../common)
|
||||||
|
target_include_directories(pm3rrg_rdv4_mbedtls INTERFACE ../../common/mbedtls)
|
||||||
target_compile_options(pm3rrg_rdv4_mbedtls PRIVATE -Wall -Werror -O3)
|
target_compile_options(pm3rrg_rdv4_mbedtls PRIVATE -Wall -Werror -O3)
|
||||||
set_property(TARGET pm3rrg_rdv4_mbedtls PROPERTY POSITION_INDEPENDENT_CODE ON)
|
set_property(TARGET pm3rrg_rdv4_mbedtls PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
MYSRCPATHS =
|
MYSRCPATHS =
|
||||||
MYINCLUDES =
|
MYINCLUDES =
|
||||||
# Strange errors on Mingw when compiling with C99
|
# Strange errors on Mingw when compiling with C99
|
||||||
MYCFLAGS = -Wno-bad-function-cast -Wno-redundant-decls -Wno-incompatible-pointer-types-discards-qualifiers -Wno-discarded-qualifiers -Wno-unknown-warning-option -Wno-maybe-uninitialized
|
MYCFLAGS = -Wno-bad-function-cast -Wno-redundant-decls -Wno-incompatible-pointer-types-discards-qualifiers -Wno-discarded-qualifiers -Wno-unknown-warning-option -Wno-maybe-uninitialized -Wno-conversion
|
||||||
MYDEFS =
|
MYDEFS =
|
||||||
MYSRCS = \
|
MYSRCS = \
|
||||||
cborencoder.c \
|
cborencoder.c \
|
||||||
|
|
|
@ -555,8 +555,11 @@ enum CborPrettyFlags {
|
||||||
CborPrettyDefaultFlags = CborPrettyIndicateIndeterminateLength
|
CborPrettyDefaultFlags = CborPrettyIndicateIndeterminateLength
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* cf https://sourceforge.net/p/mingw-w64/wiki2/gnu%20printf/ */
|
||||||
typedef CborError(*CborStreamFunction)(void *token, const char *fmt, ...)
|
typedef CborError(*CborStreamFunction)(void *token, const char *fmt, ...)
|
||||||
#ifdef __GNUC__
|
#if defined(__MINGW32__) || defined(__MINGW64__)
|
||||||
|
__attribute__((format(__MINGW_PRINTF_FORMAT, 2, 3)));
|
||||||
|
#elif defined(__GNUC__)
|
||||||
__attribute__((__format__(printf, 2, 3)))
|
__attribute__((__format__(printf, 2, 3)))
|
||||||
#endif
|
#endif
|
||||||
;
|
;
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
add_library(pm3rrg_rdv4_z STATIC
|
|
||||||
../../common/zlib/deflate.c
|
|
||||||
../../common/zlib/adler32.c
|
|
||||||
../../common/zlib/trees.c
|
|
||||||
../../common/zlib/zutil.c
|
|
||||||
../../common/zlib/inflate.c
|
|
||||||
../../common/zlib/inffast.c
|
|
||||||
../../common/zlib/inftrees.c
|
|
||||||
)
|
|
||||||
|
|
||||||
target_compile_definitions(pm3rrg_rdv4_z PRIVATE Z_SOLO NO_GZIP ZLIB_PM3_TUNED)
|
|
||||||
target_compile_options(pm3rrg_rdv4_z PRIVATE -Wall -Werror -O3)
|
|
||||||
set_property(TARGET pm3rrg_rdv4_z PROPERTY POSITION_INDEPENDENT_CODE ON)
|
|
|
@ -605,6 +605,7 @@ d58023ba2bdc # charlie
|
||||||
62ced42a6d87 # charlie
|
62ced42a6d87 # charlie
|
||||||
2548a443df28 # charlie
|
2548a443df28 # charlie
|
||||||
2ed3b15e7c0f # charlie
|
2ed3b15e7c0f # charlie
|
||||||
|
f66224ee1e89 # charlie
|
||||||
#
|
#
|
||||||
60012e9ba3fa
|
60012e9ba3fa
|
||||||
#
|
#
|
||||||
|
@ -741,7 +742,6 @@ D3A297DC2698
|
||||||
9EA3387A63C1
|
9EA3387A63C1
|
||||||
A3FAA6DAFF67
|
A3FAA6DAFF67
|
||||||
A7141147D430
|
A7141147D430
|
||||||
AAFB06045877
|
|
||||||
ACFFFFFFFFFF
|
ACFFFFFFFFFF
|
||||||
AFCEF64C9913
|
AFCEF64C9913
|
||||||
B27ADDFB64B0
|
B27ADDFB64B0
|
||||||
|
@ -763,7 +763,6 @@ FD8705E721B0
|
||||||
00ada2cd516d
|
00ada2cd516d
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
D3F7D3F7D3F7
|
|
||||||
##
|
##
|
||||||
237a4d0d9119
|
237a4d0d9119
|
||||||
0ed7846c2bc9
|
0ed7846c2bc9
|
||||||
|
@ -1068,7 +1067,6 @@ a2a3cca2a3cc
|
||||||
385efa542907
|
385efa542907
|
||||||
3864fcba5937
|
3864fcba5937
|
||||||
3f3865fccb69
|
3f3865fccb69
|
||||||
5c8ff9990da2
|
|
||||||
6291b3860fc8
|
6291b3860fc8
|
||||||
63fca9492f38
|
63fca9492f38
|
||||||
863fcb959373
|
863fcb959373
|
||||||
|
@ -1114,7 +1112,6 @@ fe04ecfe5577
|
||||||
5a7a52d5e20d # Bosch Solution 6000
|
5a7a52d5e20d # Bosch Solution 6000
|
||||||
#
|
#
|
||||||
# Found in TagInfo app
|
# Found in TagInfo app
|
||||||
8A19D40CF2B5 # Hotel key card key
|
|
||||||
C1E51C63B8F5 # RATB key
|
C1E51C63B8F5 # RATB key
|
||||||
1DB710648A65
|
1DB710648A65
|
||||||
18F34C92A56E # E-GO card key
|
18F34C92A56E # E-GO card key
|
||||||
|
|
|
@ -24,6 +24,8 @@ A5B4C3D2
|
||||||
575F4F4B
|
575F4F4B
|
||||||
#
|
#
|
||||||
50520901
|
50520901
|
||||||
|
# default PROX
|
||||||
|
50524F58
|
||||||
# Default pwd, simple:
|
# Default pwd, simple:
|
||||||
00000000
|
00000000
|
||||||
11111111
|
11111111
|
||||||
|
|
|
@ -9,7 +9,7 @@ local floor = math.floor
|
||||||
|
|
||||||
copyright = ''
|
copyright = ''
|
||||||
author = "Iceman"
|
author = "Iceman"
|
||||||
version = 'v1.0.2'
|
version = 'v1.0.3'
|
||||||
desc =[[
|
desc =[[
|
||||||
This script will program a T55x7 TAG with a configuration and four blocks of data.
|
This script will program a T55x7 TAG with a configuration and four blocks of data.
|
||||||
It will then try to detect and read back those block data and compare if read data matches the expected data.
|
It will then try to detect and read back those block data and compare if read data matches the expected data.
|
||||||
|
@ -31,12 +31,17 @@ testsuit for T55XX commands demodulation
|
||||||
]]
|
]]
|
||||||
example = [[
|
example = [[
|
||||||
1. script run test_t55x7
|
1. script run test_t55x7
|
||||||
|
2. script run test_t55x7 -t FSK2A
|
||||||
|
3. script run test_t55x7 -t PSK1
|
||||||
]]
|
]]
|
||||||
usage = [[
|
usage = [[
|
||||||
script run test_t55x7 [-h]
|
script run test_t55x7 [-h] [-t <modulation type>
|
||||||
]]
|
]]
|
||||||
arguments = [[
|
arguments = [[
|
||||||
-h this help
|
-h this help
|
||||||
|
-t (optional, defaults to ASK) 'PSK1', 'PSK2', 'PSK3',
|
||||||
|
'FSK1', 'FSK2', 'FSK1A', 'FSK2A',
|
||||||
|
'ASK', 'BI'
|
||||||
]]
|
]]
|
||||||
|
|
||||||
local DEBUG = true -- the debug flag
|
local DEBUG = true -- the debug flag
|
||||||
|
@ -303,9 +308,11 @@ local function main(args)
|
||||||
print( string.rep('--',20) )
|
print( string.rep('--',20) )
|
||||||
print( string.rep('--',20) )
|
print( string.rep('--',20) )
|
||||||
|
|
||||||
|
local modulation_type = 'ASK'
|
||||||
-- Arguments for the script
|
-- Arguments for the script
|
||||||
for o, arg in getopt.getopt(args, 'h') do
|
for o, arg in getopt.getopt(args, 'ht:') do
|
||||||
if o == 'h' then return help() end
|
if o == 'h' then return help() end
|
||||||
|
if o == 't' then modulation_type = arg end
|
||||||
end
|
end
|
||||||
|
|
||||||
core.clearCommandBuffer()
|
core.clearCommandBuffer()
|
||||||
|
@ -313,7 +320,8 @@ local function main(args)
|
||||||
|
|
||||||
-- Adjust this table to set which configurations should be tested
|
-- Adjust this table to set which configurations should be tested
|
||||||
-- local test_modes = { 'PSK1', 'PSK2', 'PSK3', 'FSK1', 'FSK2', 'FSK1A', 'FSK2A', 'ASK', 'BI' }
|
-- local test_modes = { 'PSK1', 'PSK2', 'PSK3', 'FSK1', 'FSK2', 'FSK1A', 'FSK2A', 'ASK', 'BI' }
|
||||||
local test_modes = { 'ASK' }
|
--local test_modes = { 'PSK1' }
|
||||||
|
local test_modes = { modulation_type }
|
||||||
|
|
||||||
for _ = 1, #test_modes do
|
for _ = 1, #test_modes do
|
||||||
res = WipeCard()
|
res = WipeCard()
|
||||||
|
|
|
@ -7,15 +7,15 @@ local ansicolors = require('ansicolors')
|
||||||
|
|
||||||
copyright = ''
|
copyright = ''
|
||||||
author = 'Iceman'
|
author = 'Iceman'
|
||||||
version = 'v1.0.2'
|
version = 'v1.0.3'
|
||||||
desc = [[
|
desc = [[
|
||||||
This script will load several traces files in ../traces/ folder and do
|
This script will load several traces files in current working directory/traces/ folder and do
|
||||||
"data load"
|
"data load"
|
||||||
"lf search 1 u"
|
"lf search 1 u"
|
||||||
|
|
||||||
The following tracefiles will be loaded:
|
The following tracefiles will be loaded:
|
||||||
em*.pm3
|
em*.pm3
|
||||||
m*.pm3
|
modulation*.pm3
|
||||||
]]
|
]]
|
||||||
example = [[
|
example = [[
|
||||||
1. script run tracetest
|
1. script run tracetest
|
||||||
|
@ -78,8 +78,10 @@ local function main(args)
|
||||||
print( string.rep('--',20) )
|
print( string.rep('--',20) )
|
||||||
|
|
||||||
local cmdDataLoad = 'data load %s';
|
local cmdDataLoad = 'data load %s';
|
||||||
local tracesEM = "find '../traces/' -iname 'em*.pm3' -type f"
|
local cwd = core.cwd();
|
||||||
local tracesMOD = "find '../traces/' -iname 'm*.pm3' -type f"
|
|
||||||
|
local tracesEM = "find '"..cwd.."/traces/ ' -iname 'em*.pm3' -type f"
|
||||||
|
local tracesMOD = "find '"..cwd.."/traces/' -iname 'modulation*.pm3' -type f"
|
||||||
|
|
||||||
local write2File = false
|
local write2File = false
|
||||||
local outputTemplate = os.date('testtest_%Y-%m-%d_%H%M%S')
|
local outputTemplate = os.date('testtest_%Y-%m-%d_%H%M%S')
|
||||||
|
@ -100,7 +102,7 @@ local function main(args)
|
||||||
end
|
end
|
||||||
p.close();
|
p.close();
|
||||||
|
|
||||||
-- Find a set of traces staring with MOD
|
-- Find a set of traces staring with MODULATION
|
||||||
p = assert( io.popen(tracesMOD) )
|
p = assert( io.popen(tracesMOD) )
|
||||||
for file in p:lines() do
|
for file in p:lines() do
|
||||||
table.insert(files, file)
|
table.insert(files, file)
|
||||||
|
|
99
client/pyscripts/findbits.py
Executable file
99
client/pyscripts/findbits.py
Executable file
|
@ -0,0 +1,99 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
# findbits.py - find Binary, Octal, Decimal or Hex number in bitstream
|
||||||
|
#
|
||||||
|
# Adam Laurie <adam@algroup.co.uk>
|
||||||
|
# http://rfidiot.org/
|
||||||
|
#
|
||||||
|
# This code is copyright (c) Adam Laurie, 2009, All rights reserved.
|
||||||
|
# For non-commercial use only, the following terms apply - for all other
|
||||||
|
# uses, please contact the author:
|
||||||
|
#
|
||||||
|
# This code is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This code is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
|
||||||
|
# invert binary string
|
||||||
|
def invert(data):
|
||||||
|
return ''.join('0' if c == '1' else '1' for c in data)
|
||||||
|
|
||||||
|
# do the actual search
|
||||||
|
def search(target,data):
|
||||||
|
location = data.find(target)
|
||||||
|
if location >= 0:
|
||||||
|
print('*** Match at bit {:d}: {}<{}>{}'.format(location, data[:location],target,data[location+len(target):]))
|
||||||
|
else:
|
||||||
|
print('Not found')
|
||||||
|
|
||||||
|
# convert integer to binary string
|
||||||
|
def binstring(number):
|
||||||
|
return bin(number)[2:] if number > 0 else ''
|
||||||
|
|
||||||
|
# reverse string order
|
||||||
|
def stringreverse(data):
|
||||||
|
return data[::-1]
|
||||||
|
|
||||||
|
# match forward, backward and inverted
|
||||||
|
def domatch(binary,number):
|
||||||
|
reversed= stringreverse(number)
|
||||||
|
inverted= invert(binary)
|
||||||
|
|
||||||
|
print(' Forward: (%s) ' % number, end = '')
|
||||||
|
search(binary,number)
|
||||||
|
print(' Reverse: (%s) ' % reversed, end = '')
|
||||||
|
search(binary,reversed)
|
||||||
|
print(' Inverse: (%s) ' % inverted)
|
||||||
|
print(' Forward: (%s) ' % number, end = '')
|
||||||
|
search(inverted,number)
|
||||||
|
print(' Reverse: (%s) ' % reversed, end = '')
|
||||||
|
search(inverted,reversed)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
if(len(sys.argv) < 3):
|
||||||
|
print("""
|
||||||
|
\t{0} - Search bitstream for a known number
|
||||||
|
|
||||||
|
Usage: {0} <NUMBER> <BITSTREAM>
|
||||||
|
|
||||||
|
\tNUMBER will be converted to it\'s BINARY equivalent for all valid
|
||||||
|
\tinstances of BINARY, OCTAL, DECIMAL and HEX, and the bitstream
|
||||||
|
\tand it\'s inverse will be searched for a pattern match. Note that
|
||||||
|
\tNUMBER must be specified in BINARY to match leading zeros.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
\t{0} 73 0110010101110011
|
||||||
|
""".format(sys.argv[0]))
|
||||||
|
os._exit(True)
|
||||||
|
|
||||||
|
bases= {
|
||||||
|
2:'BINARY',
|
||||||
|
8:'OCTAL',
|
||||||
|
10:'DECIMAL',
|
||||||
|
16:'HEX',
|
||||||
|
}
|
||||||
|
|
||||||
|
for base, base_name in sorted(bases.items()):
|
||||||
|
try:
|
||||||
|
number= int(sys.argv[1],base)
|
||||||
|
print('\nTrying ' + base_name)
|
||||||
|
# do BINARY as specified to preserve leading zeros
|
||||||
|
if base == 2:
|
||||||
|
domatch(sys.argv[1],sys.argv[2])
|
||||||
|
else:
|
||||||
|
domatch(binstring(number),sys.argv[2])
|
||||||
|
except:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
4
client/pyscripts/ice.py
Normal file
4
client/pyscripts/ice.py
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
print("SP %s" % sys.path)
|
78
client/pyscripts/parity.py
Normal file
78
client/pyscripts/parity.py
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
# This code is contributed by
|
||||||
|
# Shubham Singh(SHUBHAMSINGH10)
|
||||||
|
# 2020, modified (@iceman1001)
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
# Python3 program to illustrate Compute the
|
||||||
|
# parity of a number using XOR
|
||||||
|
# Generating the look-up table while pre-processing
|
||||||
|
def P2(n, table):
|
||||||
|
table.extend([n, n ^ 1, n ^ 1, n])
|
||||||
|
def P4(n, table):
|
||||||
|
return (P2(n, table), P2(n ^ 1, table),
|
||||||
|
P2(n ^ 1, table), P2(n, table))
|
||||||
|
def P6(n, table):
|
||||||
|
return (P4(n, table), P4(n ^ 1, table),
|
||||||
|
P4(n ^ 1, table), P4(n, table))
|
||||||
|
def LOOK_UP(table):
|
||||||
|
return (P6(0, table), P6(1, table),
|
||||||
|
P6(1, table), P6(0, table))
|
||||||
|
|
||||||
|
# LOOK_UP is the macro expansion to generate the table
|
||||||
|
table = [0] * 256
|
||||||
|
LOOK_UP(table)
|
||||||
|
|
||||||
|
# Function to find the parity
|
||||||
|
def Parity(num) :
|
||||||
|
# Number is considered to be of 32 bits
|
||||||
|
max = 16
|
||||||
|
|
||||||
|
# Dividing the number o 8-bit
|
||||||
|
# chunks while performing X-OR
|
||||||
|
while (max >= 8):
|
||||||
|
num = num ^ (num >> max)
|
||||||
|
max = max // 2
|
||||||
|
|
||||||
|
# Masking the number with 0xff (11111111)
|
||||||
|
# to produce valid 8-bit result
|
||||||
|
return table[num & 0xff]
|
||||||
|
|
||||||
|
def main():
|
||||||
|
if(len(sys.argv) < 2):
|
||||||
|
print("""
|
||||||
|
\t{0} - Calculate parity of a given number
|
||||||
|
|
||||||
|
Usage: {0} <2,10,16> <number>
|
||||||
|
|
||||||
|
\t Specify type as in 2 Bin, 10 Decimal, 16 Hex, and number in that particular format
|
||||||
|
\t number can only be 32bit long.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
\t{0} 10 1234
|
||||||
|
|
||||||
|
Should produce the output:
|
||||||
|
|
||||||
|
\tOdd parity\n""".format(sys.argv[0]))
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
numtype= int(sys.argv[1], 10)
|
||||||
|
print("numtype: {0}".format(numtype))
|
||||||
|
input= int(sys.argv[2], numtype)
|
||||||
|
print("num: {0} 0x{0:X}".format(input))
|
||||||
|
|
||||||
|
#num = "001111100010100011101010111101011110"
|
||||||
|
# Result is 1 for odd parity
|
||||||
|
# 0 for even parity
|
||||||
|
# result = Parity( int(input, numtype) )
|
||||||
|
result = Parity(input)
|
||||||
|
print("Odd parity") if result else print("Even parity")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
|
|
||||||
|
|
||||||
|
|
26
client/pyscripts/pm3_eml2mfd.py
Executable file
26
client/pyscripts/pm3_eml2mfd.py
Executable file
|
@ -0,0 +1,26 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
'''
|
||||||
|
# Andrei Costin <zveriu@gmail.com>, 2011
|
||||||
|
# pm3_eml2mfd.py
|
||||||
|
# Converts PM3 Mifare Classic emulator EML text file to MFD binary dump file
|
||||||
|
'''
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import binascii
|
||||||
|
|
||||||
|
def main(argv):
|
||||||
|
argc = len(argv)
|
||||||
|
if argc < 3:
|
||||||
|
print('Usage:', argv[0], 'input.eml output.mfd')
|
||||||
|
return 1
|
||||||
|
|
||||||
|
with open(argv[1], "r") as file_inp, open(argv[2], "wb") as file_out:
|
||||||
|
for line in file_inp:
|
||||||
|
line = line.rstrip('\n').rstrip('\r')
|
||||||
|
print(line)
|
||||||
|
data = binascii.unhexlify(line)
|
||||||
|
file_out.write(data)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main(sys.argv)
|
51
client/pyscripts/pm3_eml_mfd_test.py
Executable file
51
client/pyscripts/pm3_eml_mfd_test.py
Executable file
|
@ -0,0 +1,51 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
from tempfile import mkdtemp
|
||||||
|
from shutil import rmtree
|
||||||
|
from string import hexdigits
|
||||||
|
import unittest, os
|
||||||
|
import pm3_eml2mfd, pm3_mfd2eml
|
||||||
|
|
||||||
|
class TestEmlMfd(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.tmpdir = mkdtemp()
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
rmtree(self.tmpdir)
|
||||||
|
|
||||||
|
EML2MFD_TESTCASES = [
|
||||||
|
('', ''),
|
||||||
|
("41424344\r\n45464748\n494A4B4C\n", "ABCDEFGHIJKL")
|
||||||
|
]
|
||||||
|
def test_eml2mfd(self):
|
||||||
|
self.three_argument_test(pm3_eml2mfd.main, self.EML2MFD_TESTCASES)
|
||||||
|
|
||||||
|
def test_mfd2eml(self):
|
||||||
|
self.three_argument_test(pm3_mfd2eml.main,
|
||||||
|
map(reversed, self.EML2MFD_TESTCASES), c14n=hex_c14n)
|
||||||
|
|
||||||
|
def three_argument_test(self, operation, cases, c14n=str):
|
||||||
|
for case_input, case_output in cases:
|
||||||
|
try:
|
||||||
|
inp_name = os.path.join(self.tmpdir, 'input')
|
||||||
|
out_name = os.path.join(self.tmpdir, 'output')
|
||||||
|
with open(inp_name, 'w') as in_file:
|
||||||
|
in_file.write(case_input)
|
||||||
|
operation(['', inp_name, out_name])
|
||||||
|
with open(out_name, 'r') as out_file:
|
||||||
|
self.assertEqual(c14n(case_output), c14n(out_file.read()))
|
||||||
|
finally:
|
||||||
|
for file_name in inp_name, out_name:
|
||||||
|
if os.path.exists(file_name):
|
||||||
|
os.remove(file_name)
|
||||||
|
|
||||||
|
|
||||||
|
def hex_c14n(inp):
|
||||||
|
"""
|
||||||
|
Canonicalizes the input string by removing non-hexadecimal
|
||||||
|
characters and making everything uppercase
|
||||||
|
"""
|
||||||
|
return ''.join(c.upper() for c in inp if c in hexdigits)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
28
client/pyscripts/pm3_mfd2eml.py
Executable file
28
client/pyscripts/pm3_mfd2eml.py
Executable file
|
@ -0,0 +1,28 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
'''
|
||||||
|
# Andrei Costin <zveriu@gmail.com>, 2011
|
||||||
|
# pm3_eml2mfd.py
|
||||||
|
# Converts PM3 Mifare Classic MFD binary dump file to emulator EML text file
|
||||||
|
'''
|
||||||
|
import sys
|
||||||
|
|
||||||
|
READ_BLOCKSIZE = 16
|
||||||
|
|
||||||
|
def main(argv):
|
||||||
|
argc = len(argv)
|
||||||
|
if argc < 3:
|
||||||
|
print('Usage:', argv[0], 'input.mfd output.eml')
|
||||||
|
return 1
|
||||||
|
|
||||||
|
with open(argv[1], "rb") as file_inp, open(argv[2], "w") as file_out:
|
||||||
|
while True:
|
||||||
|
byte_s = file_inp.read(READ_BLOCKSIZE)
|
||||||
|
if not byte_s:
|
||||||
|
break
|
||||||
|
hex_char_repr = byte_s.hex()
|
||||||
|
file_out.write(hex_char_repr)
|
||||||
|
file_out.write("\n")
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main(sys.argv)
|
82
client/pyscripts/theremin.py
Executable file
82
client/pyscripts/theremin.py
Executable file
|
@ -0,0 +1,82 @@
|
||||||
|
#!/usr/bin/python3
|
||||||
|
|
||||||
|
### Parameters
|
||||||
|
# Sound output parameters
|
||||||
|
volume = 1.0
|
||||||
|
sample_buf_size = 44
|
||||||
|
sampling_freq = 44100 #Hz
|
||||||
|
|
||||||
|
# Frequency generator parameters
|
||||||
|
min_freq = 200 #Hz
|
||||||
|
max_freq = 2000 #Hz
|
||||||
|
|
||||||
|
# Proxmark3 parameters
|
||||||
|
pm3_client="/usr/local/bin/proxmark3"
|
||||||
|
pm3_reader_dev_file="/dev/ttyACM0"
|
||||||
|
pm3_tune_cmd="hf tune"
|
||||||
|
|
||||||
|
|
||||||
|
### Modules
|
||||||
|
import numpy
|
||||||
|
import pyaudio
|
||||||
|
from select import select
|
||||||
|
from subprocess import Popen, DEVNULL, PIPE
|
||||||
|
|
||||||
|
|
||||||
|
### Main program
|
||||||
|
p = pyaudio.PyAudio()
|
||||||
|
|
||||||
|
# For paFloat32 sample values must be in range [-1.0, 1.0]
|
||||||
|
stream = p.open(format=pyaudio.paFloat32,
|
||||||
|
channels=1,
|
||||||
|
rate=sampling_freq,
|
||||||
|
output=True)
|
||||||
|
|
||||||
|
# Initial voltage to frequency values
|
||||||
|
min_v = 100.0
|
||||||
|
max_v = 0.0
|
||||||
|
v = 0
|
||||||
|
out_freq = min_freq
|
||||||
|
|
||||||
|
# Spawn the Proxmark3 client
|
||||||
|
pm3_proc = Popen([pm3_client, pm3_reader_dev_file, "-c", pm3_tune_cmd],
|
||||||
|
bufsize=0, env={}, stdin=DEVNULL, stdout=PIPE, stderr=DEVNULL)
|
||||||
|
mv_recbuf = ""
|
||||||
|
|
||||||
|
# Read voltages from the Proxmark3, generate the sine wave, output to soundcard
|
||||||
|
sample_buf = [0.0 for x in range(0, sample_buf_size)]
|
||||||
|
i = 0
|
||||||
|
sinev = 0
|
||||||
|
while True:
|
||||||
|
|
||||||
|
# Read Proxmark3 client's stdout and extract voltage values
|
||||||
|
if(select([pm3_proc.stdout], [], [], 0)[0]):
|
||||||
|
|
||||||
|
b = pm3_proc.stdout.read(256).decode("ascii")
|
||||||
|
if "Done" in b:
|
||||||
|
break;
|
||||||
|
for c in b:
|
||||||
|
if c in "0123456789 mV":
|
||||||
|
mv_recbuf += c
|
||||||
|
else:
|
||||||
|
mv_recbuf = ""
|
||||||
|
if mv_recbuf[-3:] == " mV":
|
||||||
|
v = int(mv_recbuf[:-3]) / 1000
|
||||||
|
if v < min_v:
|
||||||
|
min_v = v - 0.001
|
||||||
|
if v > max_v:
|
||||||
|
max_v = v
|
||||||
|
|
||||||
|
# Recalculate the audio frequency to generate
|
||||||
|
out_freq = (max_freq - min_freq) * (max_v - v) / (max_v - min_v) \
|
||||||
|
+ min_freq
|
||||||
|
|
||||||
|
# Generate the samples and write them to the soundcard
|
||||||
|
sinevs = out_freq / sampling_freq * numpy.pi * 2
|
||||||
|
sample_buf[i] = sinev
|
||||||
|
sinev += sinevs
|
||||||
|
sinev = sinev if sinev < numpy.pi * 2 else sinev - numpy.pi * 2
|
||||||
|
i = (i + 1) % sample_buf_size
|
||||||
|
if not i:
|
||||||
|
stream.write((numpy.sin(sample_buf) * volume).
|
||||||
|
astype(numpy.float32).tobytes())
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue